diff --git a/lib/providers/tasks_provider.dart b/lib/providers/tasks_provider.dart index d15a5f77..c7999dab 100644 --- a/lib/providers/tasks_provider.dart +++ b/lib/providers/tasks_provider.dart @@ -1102,6 +1102,36 @@ class TasksController { } if (status == 'completed') { + // Check for IT staff assignment + final assignmentRows = await _client + .from('task_assignments') + .select('user_id') + .eq('task_id', taskId); + final assignedUserIds = (assignmentRows as List) + .map((row) => row['user_id']?.toString()) + .whereType() + .where((id) => id.isNotEmpty) + .toSet() + .toList(); + if (assignedUserIds.isEmpty) { + throw Exception( + 'Assign at least one IT Staff before completing this task.', + ); + } + + final itStaffRows = await _client + .from('profiles') + .select('id') + .inFilter('id', assignedUserIds) + .eq('role', 'it_staff'); + final hasItStaff = (itStaffRows as List).isNotEmpty; + if (!hasItStaff) { + throw Exception( + 'Assign at least one IT Staff before completing this task.', + ); + } + + // Check required fields try { final rt = taskRow['request_type']; final rc = taskRow['request_category']; diff --git a/lib/screens/tasks/task_detail_screen.dart b/lib/screens/tasks/task_detail_screen.dart index 4e55b5ea..8c0872ee 100644 --- a/lib/screens/tasks/task_detail_screen.dart +++ b/lib/screens/tasks/task_detail_screen.dart @@ -3503,12 +3503,8 @@ class _TaskDetailScreenState extends ConsumerState return chip; } - final statusOptions = _statusOptions.where((status) { - if (status == 'in_progress' && !hasAssignedItStaff) { - return false; - } - return true; - }).toList(); + // Show all status options - validation happens on selection + final statusOptions = _statusOptions; return PopupMenuButton( onSelected: (value) async { @@ -3606,6 +3602,16 @@ class _TaskDetailScreenState extends ConsumerState return; } + // Validate IT staff assignment before starting or completing + if ((value == 'in_progress' || value == 'completed') && + !hasAssignedItStaff) { + showWarningSnackBar( + context, + 'Please assign at least one IT Staff member before ${value == 'in_progress' ? 'starting' : 'completing'} this task.', + ); + return; + } + // Update DB only — Supabase realtime stream will emit the // updated task list, so explicit invalidation here causes a // visible loading/refresh and is unnecessary.