Added guard patrol day count chart

This commit is contained in:
dhanabalan
2025-06-25 10:34:11 +05:30
parent 88cde40215
commit 3a796857b0
4 changed files with 250 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
<?php
namespace App\Filament\Pages;
use App\Filament\Widgets\GuardPatrolDayChart;
use App\Models\Plant;
use Filament\Pages\Page;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Forms\Form;
use Filament\Forms\Components\Select;
use Illuminate\Support\Facades\Auth;
class GuardPatrolDayCount extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.guard-patrol-day-count';
use HasFiltersForm;
public function mount(): void
{
session()->forget(['selected_plant']);
$this->filtersForm->fill([
'plant' => null
]);
}
public function filtersForm(Form $form): Form
{
return $form
->statePath('filters')
->schema([
Select::make('plant')
->options(Plant::pluck('name', 'id'))
->label('Select Plant')
->reactive()
->afterStateUpdated(function ($state) {
session(['selected_plant' => $state]);
$this->dispatch('patrolEntryChart');
}),
]);
}
public static function getNavigationLabel(): string
{
return 'Guard Patrol Day Count';
}
public function getHeading(): string
{
return 'Guard Patrol Day Chart';
}
public function getWidgets(): array
{
return [
GuardPatrolDayChart::class,
];
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view guard patrol day count dashboard');
}
}

View File

@@ -0,0 +1,169 @@
<?php
namespace App\Filament\Widgets;
use App\Models\GuardPatrolEntry;
use Carbon\Carbon;
use DB;
use Filament\Widgets\ChartWidget;
class GuardPatrolDayChart extends ChartWidget
{
protected static ?string $heading = 'GuardPatrolDayChart';
protected static ?string $maxHeight = '350px';
protected int|string|array $columnSpan = 12;
protected $listeners = ['patrolEntryChart'];
protected function getData(): array
{
$selectedPlant = session('selected_plant');
$activeFilter = $this->filter;
switch ($activeFilter)
{
case 'yesterday':
$startDate = now()->subDay()->startOfDay();
$endDate = now()->subDay()->endOfDay();
break;
case 'this_week':
$startDate = now()->startOfWeek();
$endDate = now()->endOfWeek();
break;
case 'this_month':
$startDate = now()->startOfMonth();
$endDate = now()->endOfMonth();
break;
default: // today
$startDate = now()->startOfDay();
$endDate = now()->endOfDay();
break;
}
$uniqueGuardNames = GuardPatrolEntry::join('guard_names', 'guard_patrol_entries.guard_name_id', '=', 'guard_names.id')
->where('guard_patrol_entries.plant_id', $selectedPlant)
->select('guard_names.id', 'guard_names.name')
->groupBy('guard_names.id', 'guard_names.name')
->orderBy('guard_names.name')
->pluck('name')
->toArray();
//dd($uniqueGuardNames);
$guardPatrols = GuardPatrolEntry::join('guard_names', 'guard_patrol_entries.guard_name_id', '=', 'guard_names.id')
->where('guard_patrol_entries.plant_id', $selectedPlant)
->whereBetween('guard_patrol_entries.patrol_time', [$startDate, $endDate])
->select('guard_names.id', 'guard_names.name', 'guard_patrol_entries.patrol_time')
->orderBy('guard_names.name')
->orderBy('guard_patrol_entries.patrol_time')
->get()
->groupBy('name');
$guardTimeSums = [];
foreach ($guardPatrols as $guardName => $patrols) {
$totalSeconds = 0;
$prevTime = null;
foreach ($patrols as $patrol)
{
$currentTime = Carbon::parse($patrol->patrol_time);
if ($prevTime)
{
$totalSeconds += abs($currentTime->diffInSeconds($prevTime));
}
$prevTime = $currentTime;
}
//$guardTimeSums[$guardName] = $totalSeconds / 60;
//$guardTimeSums[$guardName] = round($totalSeconds / 60);
$guardTimeSums[$guardName] = [
'minutes' => round($totalSeconds / 60),
'hours' => round($totalSeconds / 3600, 1),
];
}
$chartData = [];
foreach ($uniqueGuardNames as $guardName)
{
if ($activeFilter === 'today') {
$chartData[] = $guardTimeSums[$guardName]['minutes'] ?? 0;
}
elseif ($activeFilter === 'yesterday') {
$chartData[] = $guardTimeSums[$guardName]['minutes'] ?? 0;
}
else
{
$chartData[] = $guardTimeSums[$guardName]['hours'] ?? 0;
}
}
return [
'labels' => array_values($uniqueGuardNames),
'datasets' => [
[
'label' => match ($activeFilter)
{
'yesterday' => "Patrols by Guard (Yesterday) Minutes",
'this_week' => "Patrols by Guard (This Week) Hours",
'this_month' => "Patrols by Guard (This Month) Hours",
default => "Patrols by Guard (Today) Minutes",
},
'data' => $chartData,
],
],
];
}
protected function getType(): string
{
return 'bar';
}
protected function getFilters(): ?array
{
return [
'today' => 'Today',
'yesterday' => 'Yesterday',
'this_week'=> 'This Week',
'this_month'=> 'This Month',
];
}
protected function getOptions(): array
{
return [
'scales' => [
'y' => [
'beginAtZero' => true, //Start Y-axis from 0
'ticks' => [
'stepSize' => 5,
],
],
],
];
}
// protected function getOptions(): array
// {
// return [
// 'scales' => [
// 'y' => [
// 'beginAtZero' => true, // Start Y-axis from 0
// 'ticks' => [
// 'stepSize' => 5,
// ],
// ],
// ],
// 'plugins' => [
// 'tooltip' => [
// 'callbacks' => [
// 'label' => "function(context) { return context.parsed.y + ' (min)'; }",
// ],
// ],
// ],
// ];
// }
}