2026-03-15 23:48:45 +03:00

141 lines
5.0 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):
request = kwargs.pop("request", None)
user = request.user if request else None
tenant_hospital = getattr(request, "tenant_hospital", None) if request else None
super().__init__(*args, **kwargs)
# Make hospital field hidden and auto-set based on user context
self.fields["hospital"].widget = forms.HiddenInput()
self.fields["hospital"].required = False
# Set hospital value based on user context
if user:
if user.is_px_admin() and tenant_hospital:
self.fields["hospital"].initial = tenant_hospital
self.fields["hospital"].queryset = self.fields["hospital"].queryset.filter(id=tenant_hospital.id)
hospital = tenant_hospital
elif user.hospital:
self.fields["hospital"].initial = user.hospital
self.fields["hospital"].queryset = self.fields["hospital"].queryset.filter(id=user.hospital.id)
hospital = user.hospital
else:
hospital = None
self.fields["hospital"].queryset = self.fields["hospital"].queryset.none()
else:
hospital = None
# 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 departments based on hospital
if hospital:
self.fields["department"].queryset = self.fields["department"].queryset.filter(hospital=hospital)
self.fields["department"].widget.attrs["class"] = "form-select"
# Filter assignable users
from apps.accounts.models import User
if hospital:
self.fields["assigned_to"].queryset = User.objects.filter(is_active=True, hospital=hospital).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