138 lines
5.2 KiB
Python

"""
PX Action Center forms - Manual action creation and management
"""
from django import forms
from django.db.models import Q
from apps.core.models import PriorityChoices, SeverityChoices
from .models import PXAction, ActionSource, ActionStatus
class ManualActionForm(forms.ModelForm):
"""
Form for manually creating PX Actions.
Features:
- Source type selection including meeting types
- User permission-based filtering
- Cascading dropdowns (hospital → department)
- Assignment to users
"""
class Meta:
model = PXAction
fields = [
'source_type', 'title', 'description',
'hospital', 'department', 'category',
'priority', 'severity', 'assigned_to',
'due_at', 'requires_approval', 'action_plan'
]
widgets = {
'title': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Brief title for the action plan'
}),
'description': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Detailed description of the issue or improvement needed'
}),
'due_at': forms.DateTimeInput(attrs={
'type': 'datetime-local',
'class': 'form-control'
}),
'action_plan': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Proposed action steps to address the issue'
}),
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
# Make hospital field required
self.fields['hospital'].required = True
self.fields['hospital'].widget.attrs['class'] = 'form-select'
# Make source type required
self.fields['source_type'].required = True
self.fields['source_type'].widget.attrs['class'] = 'form-select'
# Make category required
self.fields['category'].required = True
self.fields['category'].widget.attrs['class'] = 'form-select'
# Make priority and severity required
self.fields['priority'].required = True
self.fields['priority'].widget.attrs['class'] = 'form-select'
self.fields['severity'].required = True
self.fields['severity'].widget.attrs['class'] = 'form-select'
# Filter hospitals based on user permissions
if user and not user.is_px_admin():
if user.hospital:
self.fields['hospital'].queryset = self.fields['hospital'].queryset.filter(
id=user.hospital.id
)
self.fields['hospital'].initial = user.hospital.id
self.fields['hospital'].widget.attrs['disabled'] = True
else:
# User doesn't have a hospital, can't create actions
self.fields['hospital'].queryset = self.fields['hospital'].queryset.none()
# Filter departments based on selected hospital
if user and user.hospital:
self.fields['department'].queryset = self.fields['department'].queryset.filter(
hospital=user.hospital
)
self.fields['department'].widget.attrs['class'] = 'form-select'
# Filter assignable users
from apps.accounts.models import User
if user and user.hospital:
self.fields['assigned_to'].queryset = User.objects.filter(
is_active=True,
hospital=user.hospital
).order_by('first_name', 'last_name')
self.fields['assigned_to'].widget.attrs['class'] = 'form-select'
elif user and user.is_px_admin():
# PX admins can assign to any active user
self.fields['assigned_to'].queryset = User.objects.filter(
is_active=True
).order_by('first_name', 'last_name')
self.fields['assigned_to'].widget.attrs['class'] = 'form-select'
else:
self.fields['assigned_to'].queryset = User.objects.none()
# Set default for requires_approval
self.fields['requires_approval'].initial = True
self.fields['requires_approval'].widget.attrs['class'] = 'form-check-input'
def clean_hospital(self):
"""Validate hospital field"""
hospital = self.cleaned_data.get('hospital')
if not hospital:
raise forms.ValidationError("Hospital is required.")
return hospital
def clean_due_at(self):
"""Validate due date is in the future"""
due_at = self.cleaned_data.get('due_at')
if due_at:
from django.utils import timezone
if due_at <= timezone.now():
raise forms.ValidationError("Due date must be in the future.")
return due_at
def save(self, commit=True):
"""Save action with manual source type"""
action = super().save(commit=False)
action.source_type = ActionSource.MANUAL
if commit:
action.save()
return action