10 KiB
10 KiB
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
- Navigate to Django Admin → OT → OT Consultations
- Click "Add OT Consultation"
- Fill in patient and provider information
- 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)
- Save - scores calculate automatically
- 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 Patientconsultation_date- Date of consultationprovider- ForeignKey to User (OT therapist)referral_reason- Choice field (5 options)motor_learning_difficulty- Booleanmotor_skill_regression- Booleaneats_healthy_variety- Booleaneats_variety_textures- Booleanparticipates_family_meals- Booleanrecommendation- Choice fieldrecommendation_notes- Auto-generated or manualclinician_name- Textclinician_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)
- Developmental regression reported
- Irregular sleep patterns (infancy)
- Feeding difficulty with textures
- Frequent aggressive behavior (fights)
- Frequent temper tantrums
- High restlessness and inattention
- 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
- Always initialize consultation data after creating a new consultation
- Recalculate scores after updating any related data
- Use formsets for managing related data in views
- Check critical flags in the score summary
- Configure scoring per tenant for customization
- Use admin actions for bulk score recalculation
- Monitor required milestones (sitting, crawling, walking)
- 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