forget(['selected_plant']); session()->forget(['selected_date']); session()->forget(['selected_name']); session()->forget(['selected_time']); session()->forget(['valid_sessions']); $this->filtersForm->fill([ 'plant' => null, 'date' => null, 'time_range' => null, 'guard_name' => null ]); } public function filtersForm(Form $form): Form { return $form ->statePath('filters') ->schema([ Select::make('plant') ->label('Select Plant') //->options(Plant::pluck('name', 'id')) ->options(function (callable $get) { $userHas = Filament::auth()->user()->plant_id; return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray(); }) ->reactive() ->required() ->afterStateUpdated(function ($state,callable $set) { if (is_null($state)) { session()->forget('selected_plant'); } else { session(['selected_plant' => $state]); } session(['selected_plant' => $state]); $set('date', null); session()->forget('selected_date'); $set('guard_name', null); session()->forget('selected_name'); $set('time_range', null); session()->forget('selected_time'); session()->forget('valid_sessions'); // $this->dispatch('patrolEntryChart'); }), DatePicker::make('date') ->label('Select Date') ->placeholder('Select Date') ->reactive() ->required() ->beforeOrEqual(now()) ->default(now()->format('Y-m-d')) ->afterStateUpdated(function ($state,callable $set) { session(['selected_date' => $state]); $set('guard_name', null); session()->forget('selected_name'); $set('time_range', null); session()->forget('selected_time'); session()->forget('valid_sessions'); // $this->dispatch('patrolEntryChart'); }), Select::make('guard_name') ->label('Guard Name') ->options(function (callable $get) { $plantId = $get('plant'); $Date = $get('date'); if (!$plantId || !$Date) { return []; } return GuardPatrolEntry::with('guardNames')->where('plant_id', $plantId) ->whereDate('patrol_time', $Date)->orderBy('patrol_time','asc') ->get() ->unique('guard_name_id') ->pluck('guardNames.name', 'guard_name_id') ->toArray(); }) ->reactive() ->required() ->afterStateUpdated(function ($state,callable $set) { if (is_null($state)) { session()->forget('selected_name'); } else { session(['selected_name' => $state]); } // Clear the time range field and its session $set('time_range', null); session()->forget('selected_time'); session()->forget('valid_sessions'); }), // Select::make('time_range') // ->label('Patrol Time Range') // ->options(function (callable $get) { // $plantId = $get('plant'); // $guardId = $get('guard_name'); // $date = $get('date'); // if (!$plantId || !$guardId || !$date) { // return []; // } // $patrols = GuardPatrolEntry::where('plant_id', $plantId) // ->where('guard_name_id', $guardId) // ->whereDate('patrol_time', $date) // ->orderBy('patrol_time', 'asc') // ->get(['patrol_time']); // if ($patrols->isEmpty()) // { // return []; // } // $chunkSize = CheckPointTime::where('plant_id', $plantId)->count()+ 1;; // $chunks = $patrols->chunk($chunkSize); // $options = []; // foreach ($chunks as $index => $chunk) { // $first = $chunk->first(); // $last = $chunk->last(); // $start = Carbon::parse($first->patrol_time)->format('H:i:s'); // $end = Carbon::parse($last->patrol_time)->format('H:i:s'); // $timeRange = "$start - $end"; // $options[$timeRange] = $timeRange; // } // return $options; // }) // ->reactive() // ->required() // ->afterStateUpdated(function ($state) { // session(['selected_time' => $state]); // }) Select::make('time_range') ->label('Patrol Time Range') ->options(function (callable $get) { $plantId = $get('plant'); $guardId = $get('guard_name'); $date = $get('date'); if (!$plantId || !$guardId || !$date) { session(['valid_sessions' => []]); return []; } // Get patrols with checkpoints $patrols = GuardPatrolEntry::where('plant_id', $plantId) ->where('guard_name_id', $guardId) ->whereDate('patrol_time', $date) ->orderBy('patrol_time', 'asc') ->get(['patrol_time', 'check_point_name_id']); if ($patrols->isEmpty()) { session(['valid_sessions' => []]); return []; } // Get checkpoint sequence $checkPointTimes = CheckPointTime::where('plant_id', $plantId) ->orderBy('sequence_number') ->get(['check_point1_id', 'check_point2_id']); // Build expected sequence $expectedSequence = []; foreach ($checkPointTimes as $row) { $expectedSequence[] = $row->check_point1_id; } if ($checkPointTimes->isNotEmpty()) { $expectedSequence[] = $checkPointTimes->last()->check_point2_id; } $chunkSize = $checkPointTimes->count() + 1; $chunks = $patrols->chunk($chunkSize); $options = []; $validSessions = []; foreach ($chunks as $index => $chunk) { $first = $chunk->first(); $last = $chunk->last(); $start = Carbon::parse($first->patrol_time)->format('H:i:s'); $end = Carbon::parse($last->patrol_time)->format('H:i:s'); $timeRange = "$start - $end"; // Validate sequence for this chunk $currentSeqIndex = 0; $isValid = true; $anyMatch = false; foreach ($chunk as $patrol) { if ($currentSeqIndex < count($expectedSequence) && $patrol->check_point_name_id == $expectedSequence[$currentSeqIndex]) { $currentSeqIndex++; $anyMatch = true; } else { $isValid = false; } } // Consider valid only if at least one checkpoint matches $isValid = $isValid && $anyMatch; $validSessions[$timeRange] = $isValid; $options[$timeRange] = $timeRange; } session(['valid_sessions' => $validSessions]); return $options; }) ->reactive() ->required() ->afterStateUpdated(function ($state) { session(['selected_time' => $state]); }) ]) ->columns(4); } public function getWidgets(): array { return [ GuardPatrolHourlyChart::class, ]; } public static function canAccess(): bool { return Auth::check() && Auth::user()->can('view guard patrol hourly count dashboard'); } }