agdar/OT_IMPLEMENTATION_QUICK_START.md
Marwan Alwali 2f1681b18c update
2025-11-11 13:44:48 +03:00

10 KiB
Raw Permalink Blame History

OT Consultation Form - Quick Start Guide

Overview

The OT Consultation Form (OT-F-1) is now fully implemented with comprehensive database schema, automatic scoring, and dynamic configuration.

Quick Usage

Creating a New Consultation

from ot.models import OTConsult
from ot.scoring_service import initialize_consultation_data, OTScoringService

# 1. Create consultation
consult = OTConsult.objects.create(
    patient=patient,
    tenant=tenant,
    consultation_date=date.today(),
    provider=provider,
    referral_reason='Assessment'
)

# 2. Initialize all related data (auto-creates 55 records)
initialize_consultation_data(consult)

# 3. Fill in data through formsets or admin
# ... user fills in difficulty areas, milestones, skills, behaviors ...

# 4. Calculate scores
scoring_service = OTScoringService(consult)
scores = scoring_service.calculate_total_score()
scoring_service.save_scores()

# 5. View results
print(f"Total Score: {consult.total_score}")
print(f"Interpretation: {consult.score_interpretation}")
print(f"Recommendation: {consult.recommendation_notes}")

Accessing Through Admin

  1. Navigate to Django Admin → OT → OT Consultations
  2. Click "Add OT Consultation"
  3. Fill in patient and provider information
  4. Use inline editors to fill in:
    • Difficulty Areas (max 3)
    • Milestones (16 total, 3 required)
    • Self-Help Skills (15 total)
    • Infant Behaviors (12 total)
    • Current Behaviors (12 total)
  5. Save - scores calculate automatically
  6. Use "Recalculate scores" action if needed

Accessing Through Views

Create:

/ot/consult/create/?patient=<patient_id>

Update:

/ot/consult/<pk>/update/

Detail:

/ot/consult/<pk>/

Data Structure

Main Consultation Fields

  • patient - ForeignKey to Patient
  • consultation_date - Date of consultation
  • provider - ForeignKey to User (OT therapist)
  • referral_reason - Choice field (5 options)
  • motor_learning_difficulty - Boolean
  • motor_skill_regression - Boolean
  • eats_healthy_variety - Boolean
  • eats_variety_textures - Boolean
  • participates_family_meals - Boolean
  • recommendation - Choice field
  • recommendation_notes - Auto-generated or manual
  • clinician_name - Text
  • clinician_signature - Text

Difficulty Areas (max 3):

  • 12 predefined areas
  • Each with details field
  • Enforced max 3 via formset

Milestones (16 total):

  • headControl, reachObject, rollOver, fingerFeed
  • sitting (required), pullStand, crawling (required)
  • drawCircle, spoon, cutScissors
  • walking (required), drinkCup, jump, hop, hopOneFoot, bike

Self-Help Skills (15 total):

  • 8-9 months: 2 skills
  • 12-18 months: 4 skills
  • 18-24 months: 2 skills
  • 2-3 years: 4 skills
  • 3-4 years: 2 skills
  • 5-6 years: 1 skill

Infant Behaviors (12 total):

  • cried, good, alert, quiet, passive, active
  • likedHeld, resistedHeld, floppy, tense
  • sleepGood, sleepIrregular

Current Behaviors (12 total):

  • quiet, active, tires, talks, impulsive, restless
  • stubborn, resistant, fights, tantrums, clumsy, frustrated

Scoring System

Score Calculation

Self-Help (max 24):

  • Yes = 2 points
  • No = 0 points
  • 15 skills × 2 = 30 possible, capped at 24

Behavior (max 48):

  • Yes = 2 points
  • Sometimes = 1 point
  • No = 0 points
  • 24 behaviors × 2 = 48 possible

Developmental (max 6):

  • Required milestones only (sitting, crawling, walking)
  • Achieved = 2 points each
  • 3 milestones × 2 = 6 possible

Eating (max 6):

  • Yes = 2 points each
  • 3 questions × 2 = 6 possible

Total: 0-84 points

Interpretation Thresholds

Score Range Interpretation Recommendation
0-30 ⚠️ Needs Immediate Attention Immediate referral to OT and interdisciplinary evaluation
31-60 ⚠ Moderate Difficulty Start OT sessions, monitor progress in 2-4 months
61-84 Age-Appropriate Skills Regular developmental screening as preventive care

Critical Flags (Auto-detected)

  1. Developmental regression reported
  2. Irregular sleep patterns (infancy)
  3. Feeding difficulty with textures
  4. Frequent aggressive behavior (fights)
  5. Frequent temper tantrums
  6. High restlessness and inattention
  7. Strong resistance to change or routines

Dynamic Configuration

Creating Custom Scoring Config

from ot.models import OTScoringConfig

config = OTScoringConfig.objects.create(
    tenant=tenant,
    name="Custom Scoring for Ages 3-5",
    is_active=True,
    
    # Custom max scores
    self_help_max=30,
    behavior_max=50,
    developmental_max=10,
    eating_max=8,
    
    # Custom thresholds
    immediate_attention_threshold=35,
    moderate_difficulty_threshold=70,
    
    # Custom labels
    immediate_attention_label="Urgent Intervention Required",
    moderate_difficulty_label="Needs Support",
    age_appropriate_label="Developing Well",
    
    # Custom recommendations
    immediate_attention_recommendation="Custom recommendation text...",
    moderate_difficulty_recommendation="Custom recommendation text...",
    age_appropriate_recommendation="Custom recommendation text..."
)

Using Custom Config

The scoring service automatically uses the active configuration for the tenant:

scoring_service = OTScoringService(consult)
# Automatically uses tenant's active OTScoringConfig
scores = scoring_service.calculate_total_score()

API Examples

Get Score Summary

scoring_service = OTScoringService(consult)
summary = scoring_service.get_score_summary()

# Returns:
{
    'scores': {
        'self_help': 18,
        'behavior': 32,
        'developmental': 6,
        'eating': 4,
        'total': 60,
        'interpretation': '⚠ Moderate Difficulty - Follow-Up Needed',
        'recommendation': 'The child shows moderate concerns...',
        'critical_flags': ['Frequent temper tantrums'],
        'max_scores': {
            'self_help': 24,
            'behavior': 48,
            'developmental': 6,
            'eating': 6,
            'total': 84
        }
    },
    'percentages': {
        'self_help': 75.0,
        'behavior': 66.7,
        'developmental': 100.0,
        'eating': 66.7,
        'total': 71.4
    },
    'chart_data': {
        'labels': ['Self-Help', 'Behavior', 'Developmental', 'Eating'],
        'scores': [18, 32, 6, 4],
        'max_scores': [24, 48, 6, 6]
    }
}

Recalculate Scores

# After updating any related data
consult.calculate_scores()
consult.save()

# Or use the service
scoring_service = OTScoringService(consult)
scoring_service.save_scores()

Common Tasks

Add a Difficulty Area

from ot.models import OTDifficultyArea

# Check current count (max 3)
current_count = consult.difficulty_areas.count()

if current_count < 3:
    OTDifficultyArea.objects.create(
        consult=consult,
        area='sensory',
        details='Hypersensitivity to loud noises',
        order=current_count
    )

Update a Milestone

milestone = consult.milestones.get(milestone='sitting')
milestone.age_achieved = '6 months'
milestone.save()

# Recalculate scores
consult.calculate_scores()
consult.save()

Update Self-Help Skill

skill = consult.self_help_skills.get(
    age_range='2-3',
    skill_name='Able to feed self with little to no spilling'
)
skill.response = 'yes'
skill.comments = 'Mastered this skill recently'
skill.save()

# Recalculate scores
consult.calculate_scores()
consult.save()

Update Behavior

behavior = consult.current_behaviors.get(behavior='tantrums')
behavior.response = 'yes'
behavior.save()

# Recalculate scores (will add to critical flags)
consult.calculate_scores()
consult.save()

Formset Usage in Views

In Create View

def form_valid(self, form):
    # Get formsets from context
    difficulty_formset = context['difficulty_formset']
    milestone_formset = context['milestone_formset']
    # ... etc
    
    # Validate all
    if not all([difficulty_formset.is_valid(), ...]):
        return self.form_invalid(form)
    
    # Save main form
    self.object = form.save()
    
    # Initialize data
    initialize_consultation_data(self.object)
    
    # Save formsets
    difficulty_formset.instance = self.object
    difficulty_formset.save()
    # ... etc
    
    # Calculate scores
    scoring_service = OTScoringService(self.object)
    scoring_service.save_scores()
    
    return HttpResponseRedirect(self.get_success_url())

Troubleshooting

Scores Not Calculating

# Check if related data exists
print(f"Difficulty areas: {consult.difficulty_areas.count()}")
print(f"Milestones: {consult.milestones.count()}")
print(f"Self-help skills: {consult.self_help_skills.count()}")
print(f"Infant behaviors: {consult.infant_behaviors.count()}")
print(f"Current behaviors: {consult.current_behaviors.count()}")

# If counts are 0, initialize data
if consult.milestones.count() == 0:
    initialize_consultation_data(consult)

# Recalculate
scoring_service = OTScoringService(consult)
scoring_service.save_scores()

Max 3 Difficulty Areas Not Enforced

Check formset configuration:

# In forms.py
OTDifficultyAreaFormSet = inlineformset_factory(
    OTConsult,
    OTDifficultyArea,
    form=OTDifficultyAreaForm,
    extra=3,
    max_num=3,  # This enforces max 3
    can_delete=True,
    validate_max=True,  # This validates max 3
)

Custom Config Not Being Used

# Check active config
config = OTScoringConfig.objects.filter(
    tenant=consult.tenant,
    is_active=True
).first()

if not config:
    # Create default config
    config = OTScoringConfig.objects.create(
        tenant=consult.tenant,
        name="Default OT Scoring Configuration",
        is_active=True
    )

Best Practices

  1. Always initialize consultation data after creating a new consultation
  2. Recalculate scores after updating any related data
  3. Use formsets for managing related data in views
  4. Check critical flags in the score summary
  5. Configure scoring per tenant for customization
  6. Use admin actions for bulk score recalculation
  7. Monitor required milestones (sitting, crawling, walking)
  8. Enforce max 3 difficulty areas via formset validation

References

  • Full Implementation: OT_CONSULTATION_FORM_IMPLEMENTATION.md
  • Models: ot/models.py
  • Forms: ot/forms.py
  • Scoring Service: ot/scoring_service.py
  • Views: ot/views.py
  • Admin: ot/admin.py