732 lines
21 KiB
Python
732 lines
21 KiB
Python
"""
|
|
Psychology models for the Tenhal Multidisciplinary Healthcare Platform.
|
|
|
|
This module handles psychological consultations, assessments, and interventions.
|
|
"""
|
|
|
|
from django.db import models
|
|
from django.utils.translation import gettext_lazy as _
|
|
from simple_history.models import HistoricalRecords
|
|
|
|
from core.models import (
|
|
UUIDPrimaryKeyMixin,
|
|
TimeStampedMixin,
|
|
TenantOwnedMixin,
|
|
ClinicallySignableMixin,
|
|
)
|
|
|
|
|
|
class PsychologyConsultation(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""
|
|
Psychology consultation form.
|
|
Initial psychological evaluation and assessment.
|
|
"""
|
|
|
|
class ReferralReason(models.TextChoices):
|
|
BEHAVIORAL_ISSUES = 'BEHAVIORAL', _('Behavioral Issues')
|
|
EMOTIONAL_DIFFICULTIES = 'EMOTIONAL', _('Emotional Difficulties')
|
|
DEVELOPMENTAL_CONCERNS = 'DEVELOPMENTAL', _('Developmental Concerns')
|
|
LEARNING_DIFFICULTIES = 'LEARNING', _('Learning Difficulties')
|
|
SOCIAL_SKILLS = 'SOCIAL', _('Social Skills Deficits')
|
|
ANXIETY = 'ANXIETY', _('Anxiety')
|
|
DEPRESSION = 'DEPRESSION', _('Depression')
|
|
TRAUMA = 'TRAUMA', _('Trauma/PTSD')
|
|
ADHD_ASSESSMENT = 'ADHD', _('ADHD Assessment')
|
|
AUTISM_ASSESSMENT = 'AUTISM', _('Autism Spectrum Assessment')
|
|
OTHER = 'OTHER', _('Other')
|
|
|
|
# Core Relationships
|
|
patient = models.ForeignKey(
|
|
'core.Patient',
|
|
on_delete=models.CASCADE,
|
|
related_name='psychology_consultations',
|
|
verbose_name=_("Patient")
|
|
)
|
|
appointment = models.ForeignKey(
|
|
'appointments.Appointment',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='psychology_consultations',
|
|
verbose_name=_("Appointment")
|
|
)
|
|
consultation_date = models.DateField(
|
|
verbose_name=_("Consultation Date")
|
|
)
|
|
provider = models.ForeignKey(
|
|
'core.User',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
related_name='psychology_consultations_provided',
|
|
verbose_name=_("Provider")
|
|
)
|
|
|
|
# Referral Information
|
|
referral_reason = models.CharField(
|
|
max_length=50,
|
|
choices=ReferralReason.choices,
|
|
verbose_name=_("Referral Reason")
|
|
)
|
|
referral_source = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
verbose_name=_("Referral Source")
|
|
)
|
|
presenting_problem = models.TextField(
|
|
verbose_name=_("Presenting Problem")
|
|
)
|
|
|
|
# Background Information
|
|
family_history = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Family History")
|
|
)
|
|
medical_history = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Medical History")
|
|
)
|
|
developmental_history = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Developmental History")
|
|
)
|
|
educational_history = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Educational History")
|
|
)
|
|
social_history = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Social History")
|
|
)
|
|
|
|
# Mental Status Examination
|
|
appearance = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Appearance")
|
|
)
|
|
behavior = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Behavior")
|
|
)
|
|
mood = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
verbose_name=_("Mood")
|
|
)
|
|
affect = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
verbose_name=_("Affect")
|
|
)
|
|
speech = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Speech")
|
|
)
|
|
thought_process = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Thought Process")
|
|
)
|
|
thought_content = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Thought Content")
|
|
)
|
|
perception = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Perception")
|
|
)
|
|
cognition = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Cognition")
|
|
)
|
|
insight = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
verbose_name=_("Insight")
|
|
)
|
|
judgment = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
verbose_name=_("Judgment")
|
|
)
|
|
|
|
# Risk Assessment
|
|
suicide_risk = models.CharField(
|
|
max_length=50,
|
|
blank=True,
|
|
choices=[
|
|
('NONE', _('None')),
|
|
('LOW', _('Low')),
|
|
('MODERATE', _('Moderate')),
|
|
('HIGH', _('High')),
|
|
],
|
|
verbose_name=_("Suicide Risk")
|
|
)
|
|
homicide_risk = models.CharField(
|
|
max_length=50,
|
|
blank=True,
|
|
choices=[
|
|
('NONE', _('None')),
|
|
('LOW', _('Low')),
|
|
('MODERATE', _('Moderate')),
|
|
('HIGH', _('High')),
|
|
],
|
|
verbose_name=_("Homicide Risk")
|
|
)
|
|
risk_assessment_notes = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Risk Assessment Notes")
|
|
)
|
|
|
|
# Clinical Impressions
|
|
clinical_impressions = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Clinical Impressions")
|
|
)
|
|
provisional_diagnosis = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Provisional Diagnosis")
|
|
)
|
|
|
|
# Treatment Plan
|
|
treatment_goals = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Treatment Goals")
|
|
)
|
|
treatment_approach = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Treatment Approach")
|
|
)
|
|
recommendations = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Recommendations")
|
|
)
|
|
frequency_duration = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
verbose_name=_("Recommended Frequency & Duration")
|
|
)
|
|
|
|
# Referrals
|
|
referrals_needed = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Referrals Needed")
|
|
)
|
|
|
|
history = HistoricalRecords()
|
|
|
|
class Meta:
|
|
verbose_name = _("Psychology Consultation")
|
|
verbose_name_plural = _("Psychology Consultations")
|
|
ordering = ['-consultation_date', '-created_at']
|
|
indexes = [
|
|
models.Index(fields=['patient', 'consultation_date']),
|
|
models.Index(fields=['provider', 'consultation_date']),
|
|
models.Index(fields=['referral_reason']),
|
|
models.Index(fields=['tenant', 'consultation_date']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"Psychology Consultation - {self.patient} - {self.consultation_date}"
|
|
|
|
|
|
class PsychologyAssessment(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""
|
|
Psychological assessment with standardized testing.
|
|
Comprehensive evaluation using psychological tests and measures.
|
|
"""
|
|
|
|
class AssessmentType(models.TextChoices):
|
|
COGNITIVE = 'COGNITIVE', _('Cognitive Assessment')
|
|
DEVELOPMENTAL = 'DEVELOPMENTAL', _('Developmental Assessment')
|
|
BEHAVIORAL = 'BEHAVIORAL', _('Behavioral Assessment')
|
|
EMOTIONAL = 'EMOTIONAL', _('Emotional Assessment')
|
|
PERSONALITY = 'PERSONALITY', _('Personality Assessment')
|
|
NEUROPSYCHOLOGICAL = 'NEUROPSYCH', _('Neuropsychological Assessment')
|
|
COMPREHENSIVE = 'COMPREHENSIVE', _('Comprehensive Assessment')
|
|
|
|
# Core Relationships
|
|
patient = models.ForeignKey(
|
|
'core.Patient',
|
|
on_delete=models.CASCADE,
|
|
related_name='psychology_assessments',
|
|
verbose_name=_("Patient")
|
|
)
|
|
appointment = models.ForeignKey(
|
|
'appointments.Appointment',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='psychology_assessments',
|
|
verbose_name=_("Appointment")
|
|
)
|
|
assessment_date = models.DateField(
|
|
verbose_name=_("Assessment Date")
|
|
)
|
|
provider = models.ForeignKey(
|
|
'core.User',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
related_name='psychology_assessments_provided',
|
|
verbose_name=_("Provider")
|
|
)
|
|
|
|
# Assessment Details
|
|
assessment_type = models.CharField(
|
|
max_length=50,
|
|
choices=AssessmentType.choices,
|
|
verbose_name=_("Assessment Type")
|
|
)
|
|
reason_for_assessment = models.TextField(
|
|
verbose_name=_("Reason for Assessment")
|
|
)
|
|
|
|
# Background Information
|
|
relevant_history = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Relevant History")
|
|
)
|
|
current_medications = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Current Medications")
|
|
)
|
|
|
|
# Tests Administered (JSON for flexibility)
|
|
tests_administered = models.JSONField(
|
|
default=list,
|
|
blank=True,
|
|
help_text=_("List of tests with scores and interpretations"),
|
|
verbose_name=_("Tests Administered")
|
|
)
|
|
|
|
# Behavioral Observations
|
|
behavioral_observations = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Behavioral Observations During Testing")
|
|
)
|
|
test_validity = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Test Validity & Reliability")
|
|
)
|
|
|
|
# Results Summary
|
|
cognitive_functioning = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Cognitive Functioning")
|
|
)
|
|
emotional_functioning = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Emotional Functioning")
|
|
)
|
|
behavioral_functioning = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Behavioral Functioning")
|
|
)
|
|
social_functioning = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Social Functioning")
|
|
)
|
|
adaptive_functioning = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Adaptive Functioning")
|
|
)
|
|
|
|
# Strengths & Weaknesses
|
|
strengths = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Strengths")
|
|
)
|
|
weaknesses = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Areas of Concern/Weakness")
|
|
)
|
|
|
|
# Diagnosis
|
|
diagnostic_impressions = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Diagnostic Impressions")
|
|
)
|
|
dsm5_diagnosis = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("DSM-5 Diagnosis")
|
|
)
|
|
|
|
# Recommendations
|
|
recommendations = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Recommendations")
|
|
)
|
|
treatment_recommendations = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Treatment Recommendations")
|
|
)
|
|
educational_recommendations = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Educational Recommendations")
|
|
)
|
|
follow_up_recommendations = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Follow-up Recommendations")
|
|
)
|
|
|
|
history = HistoricalRecords()
|
|
|
|
class Meta:
|
|
verbose_name = _("Psychology Assessment")
|
|
verbose_name_plural = _("Psychology Assessments")
|
|
ordering = ['-assessment_date', '-created_at']
|
|
indexes = [
|
|
models.Index(fields=['patient', 'assessment_date']),
|
|
models.Index(fields=['provider', 'assessment_date']),
|
|
models.Index(fields=['assessment_type']),
|
|
models.Index(fields=['tenant', 'assessment_date']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"Psychology Assessment ({self.get_assessment_type_display()}) - {self.patient} - {self.assessment_date}"
|
|
|
|
|
|
class PsychologySession(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""
|
|
Psychology therapy session notes.
|
|
Individual or group therapy session documentation.
|
|
"""
|
|
|
|
class SessionType(models.TextChoices):
|
|
INDIVIDUAL = 'INDIVIDUAL', _('Individual Therapy')
|
|
GROUP = 'GROUP', _('Group Therapy')
|
|
FAMILY = 'FAMILY', _('Family Therapy')
|
|
PARENT_TRAINING = 'PARENT_TRAINING', _('Parent Training')
|
|
CONSULTATION = 'CONSULTATION', _('Consultation')
|
|
|
|
class TherapyModality(models.TextChoices):
|
|
CBT = 'CBT', _('Cognitive Behavioral Therapy')
|
|
DBT = 'DBT', _('Dialectical Behavior Therapy')
|
|
PSYCHODYNAMIC = 'PSYCHODYNAMIC', _('Psychodynamic Therapy')
|
|
HUMANISTIC = 'HUMANISTIC', _('Humanistic Therapy')
|
|
PLAY_THERAPY = 'PLAY_THERAPY', _('Play Therapy')
|
|
ART_THERAPY = 'ART_THERAPY', _('Art Therapy')
|
|
MINDFULNESS = 'MINDFULNESS', _('Mindfulness-Based Therapy')
|
|
SOLUTION_FOCUSED = 'SOLUTION_FOCUSED', _('Solution-Focused Therapy')
|
|
OTHER = 'OTHER', _('Other')
|
|
|
|
# Core Relationships
|
|
patient = models.ForeignKey(
|
|
'core.Patient',
|
|
on_delete=models.CASCADE,
|
|
related_name='psychology_sessions',
|
|
verbose_name=_("Patient")
|
|
)
|
|
appointment = models.ForeignKey(
|
|
'appointments.Appointment',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='psychology_sessions',
|
|
verbose_name=_("Appointment")
|
|
)
|
|
|
|
# NEW: Link to centralized session (for scheduling/capacity management)
|
|
session = models.ForeignKey(
|
|
'appointments.Session',
|
|
on_delete=models.CASCADE,
|
|
null=True,
|
|
blank=True,
|
|
related_name='psychology_notes',
|
|
verbose_name=_("Session"),
|
|
help_text=_("Link to centralized session for scheduling")
|
|
)
|
|
|
|
# NEW: Link to specific participant (for group sessions)
|
|
session_participant = models.ForeignKey(
|
|
'appointments.SessionParticipant',
|
|
on_delete=models.CASCADE,
|
|
null=True,
|
|
blank=True,
|
|
related_name='psychology_notes',
|
|
verbose_name=_("Session Participant"),
|
|
help_text=_("For group sessions: which participant these notes are for")
|
|
)
|
|
|
|
session_number = models.PositiveIntegerField(
|
|
verbose_name=_("Session Number")
|
|
)
|
|
session_date = models.DateField(
|
|
verbose_name=_("Session Date")
|
|
)
|
|
provider = models.ForeignKey(
|
|
'core.User',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
related_name='psychology_sessions_provided',
|
|
verbose_name=_("Provider")
|
|
)
|
|
|
|
# Session Details
|
|
session_type = models.CharField(
|
|
max_length=50,
|
|
choices=SessionType.choices,
|
|
verbose_name=_("Session Type")
|
|
)
|
|
therapy_modality = models.CharField(
|
|
max_length=50,
|
|
choices=TherapyModality.choices,
|
|
blank=True,
|
|
verbose_name=_("Therapy Modality")
|
|
)
|
|
duration_minutes = models.PositiveIntegerField(
|
|
null=True,
|
|
blank=True,
|
|
verbose_name=_("Duration (minutes)")
|
|
)
|
|
|
|
# Session Content
|
|
presenting_issues = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Presenting Issues This Session")
|
|
)
|
|
interventions_used = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Interventions Used")
|
|
)
|
|
client_response = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Client Response to Interventions")
|
|
)
|
|
|
|
# Progress Notes
|
|
progress_toward_goals = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Progress Toward Goals")
|
|
)
|
|
behavioral_observations = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Behavioral Observations")
|
|
)
|
|
mood_affect = models.CharField(
|
|
max_length=200,
|
|
blank=True,
|
|
verbose_name=_("Mood & Affect")
|
|
)
|
|
|
|
# Risk Assessment
|
|
current_risk_level = models.CharField(
|
|
max_length=50,
|
|
blank=True,
|
|
choices=[
|
|
('NONE', _('None')),
|
|
('LOW', _('Low')),
|
|
('MODERATE', _('Moderate')),
|
|
('HIGH', _('High')),
|
|
],
|
|
verbose_name=_("Current Risk Level")
|
|
)
|
|
risk_notes = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Risk Assessment Notes")
|
|
)
|
|
|
|
# Homework & Plan
|
|
homework_assigned = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Homework Assigned")
|
|
)
|
|
plan_for_next_session = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Plan for Next Session")
|
|
)
|
|
|
|
# Clinical Notes
|
|
clinical_notes = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Additional Clinical Notes")
|
|
)
|
|
|
|
history = HistoricalRecords()
|
|
|
|
class Meta:
|
|
verbose_name = _("Psychology Session")
|
|
verbose_name_plural = _("Psychology Sessions")
|
|
ordering = ['-session_date', '-session_number']
|
|
indexes = [
|
|
models.Index(fields=['patient', 'session_date']),
|
|
models.Index(fields=['provider', 'session_date']),
|
|
models.Index(fields=['session_number']),
|
|
models.Index(fields=['tenant', 'session_date']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"Psychology Session #{self.session_number} - {self.patient} - {self.session_date}"
|
|
|
|
|
|
class PsychologyGoal(UUIDPrimaryKeyMixin, TimeStampedMixin):
|
|
"""
|
|
Treatment goals for psychology therapy.
|
|
Tracks progress toward therapeutic objectives.
|
|
"""
|
|
|
|
class Status(models.TextChoices):
|
|
NOT_STARTED = 'NOT_STARTED', _('Not Started')
|
|
IN_PROGRESS = 'IN_PROGRESS', _('In Progress')
|
|
ACHIEVED = 'ACHIEVED', _('Achieved')
|
|
DISCONTINUED = 'DISCONTINUED', _('Discontinued')
|
|
MODIFIED = 'MODIFIED', _('Modified')
|
|
|
|
patient = models.ForeignKey(
|
|
'core.Patient',
|
|
on_delete=models.CASCADE,
|
|
related_name='psychology_goals',
|
|
verbose_name=_("Patient")
|
|
)
|
|
consultation = models.ForeignKey(
|
|
PsychologyConsultation,
|
|
on_delete=models.CASCADE,
|
|
null=True,
|
|
blank=True,
|
|
related_name='goals',
|
|
verbose_name=_("Consultation")
|
|
)
|
|
goal_description = models.TextField(
|
|
verbose_name=_("Goal Description")
|
|
)
|
|
target_date = models.DateField(
|
|
null=True,
|
|
blank=True,
|
|
verbose_name=_("Target Date")
|
|
)
|
|
status = models.CharField(
|
|
max_length=20,
|
|
choices=Status.choices,
|
|
default=Status.NOT_STARTED,
|
|
verbose_name=_("Status")
|
|
)
|
|
progress_percentage = models.PositiveSmallIntegerField(
|
|
default=0,
|
|
help_text=_("Progress percentage (0-100)"),
|
|
verbose_name=_("Progress (%)")
|
|
)
|
|
progress_notes = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Progress Notes")
|
|
)
|
|
achieved_date = models.DateField(
|
|
null=True,
|
|
blank=True,
|
|
verbose_name=_("Achieved Date")
|
|
)
|
|
|
|
class Meta:
|
|
verbose_name = _("Psychology Goal")
|
|
verbose_name_plural = _("Psychology Goals")
|
|
ordering = ['patient', 'target_date']
|
|
|
|
def __str__(self):
|
|
return f"{self.goal_description[:50]} - {self.get_status_display()}"
|
|
|
|
|
|
class PsychologyProgressReport(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""
|
|
Psychology progress report.
|
|
Comprehensive summary of treatment progress.
|
|
"""
|
|
|
|
patient = models.ForeignKey(
|
|
'core.Patient',
|
|
on_delete=models.CASCADE,
|
|
related_name='psychology_progress_reports',
|
|
verbose_name=_("Patient")
|
|
)
|
|
report_date = models.DateField(
|
|
verbose_name=_("Report Date")
|
|
)
|
|
provider = models.ForeignKey(
|
|
'core.User',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
related_name='psychology_progress_reports_provided',
|
|
verbose_name=_("Provider")
|
|
)
|
|
|
|
# Treatment Summary
|
|
treatment_start_date = models.DateField(
|
|
null=True,
|
|
blank=True,
|
|
verbose_name=_("Treatment Start Date")
|
|
)
|
|
sessions_scheduled = models.PositiveIntegerField(
|
|
default=0,
|
|
verbose_name=_("Sessions Scheduled")
|
|
)
|
|
sessions_attended = models.PositiveIntegerField(
|
|
default=0,
|
|
verbose_name=_("Sessions Attended")
|
|
)
|
|
|
|
# Progress Summary
|
|
presenting_problems_summary = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Presenting Problems Summary")
|
|
)
|
|
treatment_provided = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Treatment Provided")
|
|
)
|
|
goals_progress = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Progress Toward Goals")
|
|
)
|
|
overall_progress = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Overall Progress")
|
|
)
|
|
|
|
# Current Status
|
|
current_functioning = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Current Functioning")
|
|
)
|
|
current_symptoms = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Current Symptoms")
|
|
)
|
|
|
|
# Recommendations
|
|
recommendations = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Recommendations")
|
|
)
|
|
continue_treatment = models.BooleanField(
|
|
default=True,
|
|
verbose_name=_("Continue Treatment")
|
|
)
|
|
discharge_plan = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Discharge Plan")
|
|
)
|
|
|
|
# Prognosis
|
|
prognosis = models.TextField(
|
|
blank=True,
|
|
verbose_name=_("Prognosis")
|
|
)
|
|
|
|
history = HistoricalRecords()
|
|
|
|
class Meta:
|
|
verbose_name = _("Psychology Progress Report")
|
|
verbose_name_plural = _("Psychology Progress Reports")
|
|
ordering = ['-report_date', '-created_at']
|
|
indexes = [
|
|
models.Index(fields=['patient', 'report_date']),
|
|
models.Index(fields=['provider', 'report_date']),
|
|
models.Index(fields=['tenant', 'report_date']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"Psychology Progress Report - {self.patient} - {self.report_date}"
|
|
|
|
@property
|
|
def attendance_rate(self):
|
|
"""Calculate attendance rate percentage."""
|
|
if self.sessions_scheduled > 0:
|
|
return round((self.sessions_attended / self.sessions_scheduled) * 100, 2)
|
|
return 0
|