# 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 ```python 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= ``` **Update:** ``` /ot/consult//update/ ``` **Detail:** ``` /ot/consult// ``` ## 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 ### Related Data (Auto-initialized) **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 ```python 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: ```python scoring_service = OTScoringService(consult) # Automatically uses tenant's active OTScoringConfig scores = scoring_service.calculate_total_score() ``` ## API Examples ### Get Score Summary ```python 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 ```python # 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 ```python 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 ```python milestone = consult.milestones.get(milestone='sitting') milestone.age_achieved = '6 months' milestone.save() # Recalculate scores consult.calculate_scores() consult.save() ``` ### Update Self-Help Skill ```python 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 ```python 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 ```python 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 ```python # 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: ```python # 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 ```python # 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`