""" 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