diff --git a/app/Filament/Widgets/CumulativeChart.php b/app/Filament/Widgets/CumulativeChart.php index c30e502..091518b 100644 --- a/app/Filament/Widgets/CumulativeChart.php +++ b/app/Filament/Widgets/CumulativeChart.php @@ -11,11 +11,13 @@ class CumulativeChart extends ChartWidget protected $listeners = ['cumulativeChart']; + protected static ?string $maxHeight = '350px'; + protected int|string|array $columnSpan = 12; protected function getData(): array { - $selectedPlant = session('selected_plant') ?? session('select_plant'); + $selectedPlant = session('selected_plant'); $activeFilter = $this->filter; // Define date range based on filter diff --git a/app/Filament/Widgets/InvoiceChart.php b/app/Filament/Widgets/InvoiceChart.php index 26e8343..8322c18 100644 --- a/app/Filament/Widgets/InvoiceChart.php +++ b/app/Filament/Widgets/InvoiceChart.php @@ -15,7 +15,6 @@ class InvoiceChart extends ChartWidget protected $listeners = ['invoiceChart']; - protected function getData(): array { $selectedPlant =session('selec_plant'); @@ -33,13 +32,17 @@ class InvoiceChart extends ChartWidget } if ($activeFilter === 'yesterday') { - $startDate = now()->subDay()->startOfDay(); - $endDate = now()->subDay()->endOfDay(); + $startDate = now()->subDay()->setTime(8, 0, 0); // yesterday 8:00 AM + $endDate = now()->setTime(8, 0, 0); // today 8:00 AM $groupBy = 'EXTRACT(HOUR FROM invoice_validations.created_at)'; } else if ($activeFilter === 'this_week') { - $startDate = now()->startOfWeek(); // Monday 12:00 AM - $endDate = now()->endOfWeek(); // Sunday 11:59 PM + // Monday 8:00 AM of the current week + $startDate = now()->startOfWeek()->setTime(8, 0, 0); + + // Next Monday 8:00 AM (end of Sunday + 8 hrs) + $endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0); + $groupBy = 'EXTRACT(DOW FROM invoice_validations.created_at)'; // Group by day of week } else if ($activeFilter === 'this_month') { @@ -49,17 +52,48 @@ class InvoiceChart extends ChartWidget } else { - $startDate = now()->startOfDay(); - $endDate = now()->endOfDay(); + $startDate = now()->setTime(8, 0, 0); // today at 8:00 AM + $endDate = now()->copy()->addDay()->setTime(8, 0, 0); // tomorrow at 8:00 AM $groupBy = 'EXTRACT(HOUR FROM invoice_validations.created_at)'; } - $fullyScannedInvoiceNumbers = \DB::table('invoice_validations') - ->select('invoice_number') - ->where('plant_id', $selectedPlant) - ->groupBy('invoice_number') - ->havingRaw("SUM(CASE WHEN scanned_status = 'Scanned' THEN 1 ELSE 0 END) = COUNT(*)") - ->pluck('invoice_number'); + // $fullyScannedInvoiceNumbers = \DB::table('invoice_validations') + // ->select('invoice_number') + // ->where('plant_id', $selectedPlant) + // ->groupBy('invoice_number') + // ->havingRaw("SUM(CASE WHEN scanned_status = 'Scanned' THEN 1 ELSE 0 END) = COUNT(*)") + // ->pluck('invoice_number'); + + if ($selectedInvoice === 'individual_material') + { + $fullyScannedInvoiceNumbers = \DB::table('invoice_validations') + ->select('invoice_number') + ->where('plant_id', $selectedPlant) + ->havingRaw('MIN(quantity) = 1 AND MAX(quantity) = 1') // All rows must have quantity = 1 + ->groupBy('invoice_number') + ->havingRaw("SUM(CASE WHEN serial_number IS NOT NULL AND serial_number != '' THEN 1 ELSE 0 END) = COUNT(*)") + ->pluck('invoice_number'); + } + else if ($selectedInvoice === 'bundle_material') + { + $fullyScannedInvoiceNumbers = \DB::table('invoice_validations') + ->select('invoice_number') + ->where('plant_id', $selectedPlant) + ->havingRaw('MIN(quantity) > 1') + ->groupBy('invoice_number') + ->havingRaw("SUM(CASE WHEN serial_number IS NOT NULL AND serial_number != '' THEN 1 ELSE 0 END) = COUNT(*)") + ->pluck('invoice_number'); + } + else + { + $fullyScannedInvoiceNumbers = \DB::table('invoice_validations') + ->select('invoice_number') + ->where('plant_id', $selectedPlant) + ->groupBy('invoice_number') + ->havingRaw("SUM(CASE WHEN scanned_status = 'Scanned' THEN 1 ELSE 0 END) = COUNT(*)") + ->pluck('invoice_number'); + } + //query data $query = \DB::table('invoice_validations') @@ -173,7 +207,6 @@ class InvoiceChart extends ChartWidget ], ], ], - ]; } diff --git a/app/Filament/Widgets/ItemOverview.php b/app/Filament/Widgets/ItemOverview.php index d61db41..f3bfb13 100644 --- a/app/Filament/Widgets/ItemOverview.php +++ b/app/Filament/Widgets/ItemOverview.php @@ -39,7 +39,6 @@ class ItemOverview extends ChartWidget // Monday 8:00 AM of the current week $startDate = now()->startOfWeek()->setTime(8, 0, 0); - // Next Monday 8:00 AM (end of Sunday + 8 hrs) $endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0); $groupBy = 'EXTRACT(DOW FROM production_quantities.created_at)'; // Group by day of week @@ -178,6 +177,9 @@ class ItemOverview extends ChartWidget public static function canView(): bool { // Only show on HourlyProduction page - return request()->routeIs('filament.pages.hourly-production'); + return request()->routeIs([ + 'filament.pages.hourly-production', + 'filament.admin.resources.production-quantities.create', + ]); } } diff --git a/app/Filament/Widgets/ProductionOrderChart.php b/app/Filament/Widgets/ProductionOrderChart.php new file mode 100644 index 0000000..7b74177 --- /dev/null +++ b/app/Filament/Widgets/ProductionOrderChart.php @@ -0,0 +1,177 @@ +filter; + + $selectedPlant = session('selected_plant'); + $selectedLine = session('selected_line'); + $productionOrder = session('production_order'); + + if (!$selectedPlant || !$selectedLine || !$productionOrder) + { + return [ + 'datasets' => [], + 'labels' => [], + ]; + } + + if ($activeFilter === 'yesterday') { + $startDate = now()->subDay()->setTime(8, 0, 0); // yesterday 8:00 AM + $endDate = now()->setTime(8, 0, 0); // today 8:00 AM + $groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)'; + } + else if ($activeFilter === 'this_week') { + // Monday 8:00 AM of the current week + $startDate = now()->startOfWeek()->setTime(8, 0, 0); + + // Next Monday 8:00 AM (end of Sunday + 8 hrs) + $endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0); + + $groupBy = 'EXTRACT(DOW FROM production_quantities.created_at)'; // Group by day of week + } + + else if ($activeFilter === 'this_month') { + $startDate = now()->startOfMonth(); + $endDate = now()->endOfMonth(); + $groupBy = "FLOOR((EXTRACT(DAY FROM production_quantities.created_at) - 1) / 7) + 1"; + } + else + { + $startDate = now()->setTime(8, 0, 0); // today at 8:00 AM + $endDate = now()->copy()->addDay()->setTime(8, 0, 0); // tomorrow at 8:00 AM + $groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)'; + } + + + $query = \DB::table('production_quantities') + ->join('plants', 'production_quantities.plant_id', '=', 'plants.id') + ->join('lines', 'production_quantities.line_id', '=', 'lines.id') + ->selectRaw("$groupBy AS time_unit, count(*) AS total_quantity") + ->whereBetween('production_quantities.created_at', [$startDate, $endDate]) + ->where('plants.id', $selectedPlant) + ->where('lines.id', $selectedLine) + ->when($productionOrder, fn($q) => $q->where('production_quantities.production_order', $productionOrder)) + ->groupByRaw($groupBy) + ->orderByRaw($groupBy) + ->pluck('total_quantity', 'time_unit') + ->toArray(); + if ($activeFilter === 'this_month') { + $weeksCount = ceil($endDate->day / 7); // Calculate total weeks dynamically + $allWeeks = array_fill(1, $weeksCount, 0); // Initialize all weeks with 0 + $data = array_replace($allWeeks, $query); // Fill missing weeks with 0 + + // Generate dynamic week labels + $labels = []; + for ($i = 1; $i <= $weeksCount; $i++) { + $weekStart = $startDate->copy()->addDays(($i - 1) * 7)->format('d M'); + $weekEnd = $startDate->copy()->addDays($i * 7 - 1)->min($endDate)->format('d M'); + $labels[] = "Week $i ($weekStart - $weekEnd)"; + } + + $orderedData = array_values($data); + } + else if ($activeFilter === 'this_week') { + // Correct week labels: ['Mon', 'Tue', ..., 'Sun'] + $labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']; + + // Initialize default data for all 7 days + $data = array_fill(0, 7, 0); + + // Fill in data from query results + foreach ($query as $dow => $count) { + $data[$dow] = $count; + } + + // Ensure days are ordered from Monday to Sunday + $orderedData = [ + $data[1] ?? 0, // Monday + $data[2] ?? 0, // Tuesday + $data[3] ?? 0, // Wednesday + $data[4] ?? 0, // Thursday + $data[5] ?? 0, // Friday + $data[6] ?? 0, // Saturday + $data[0] ?? 0, // Sunday (move to last) + ]; + } + else + { + // Hourly data (same as before) + $allHours = array_fill(0, 24, 0); + $data = array_replace($allHours, $query); + + // Shift hours for proper display (8 AM to 7 AM) + $shiftedKeys = array_merge(range(8, 23), range(0, 8)); + $orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys); + + // Labels: ["8 AM", "9 AM", ..., "7 AM"] + $labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys); + } + + return [ + 'datasets' => [ + [ + 'label' => match ($activeFilter) { + 'this_week' => "Daily Production Order Count This Week", + 'this_month' => "Weekly Production Order Count This Month", // Updated Label + 'yesterday' => "Yesterday's Hourly Order Count Production", + default => "Today's Hourly Production Order Count", + }, + 'data' => $orderedData, + 'borderColor' => 'rgba(75, 192, 192, 1)', + 'backgroundColor' => 'rgba(75, 192, 192, 0.2)', + 'fill' => false, + 'tension' => 0.3, + ], + ], + 'labels' => $labels, + ]; +} + protected function getType(): string + { + return 'bar'; + } + + protected function getOptions(): array + { + return [ + + 'scales' => [ + 'y' => [ + 'beginAtZero' => true, + 'ticks' => [ + 'stepSize' => 0.5, + ], + ], + ], + ]; + } + + protected function getFilters(): ?array + { + return [ + 'today' => 'Today', + 'yesterday' => 'Yesterday', + 'this_week'=> 'This Week', + 'this_month'=> 'This Month', + ]; + } + + public static function canView(): bool + { + // Only show on HourlyProduction page + return request()->routeIs('filament.pages.production-order-count'); + } +} diff --git a/resources/views/filament/pages/production-order-count.blade.php b/resources/views/filament/pages/production-order-count.blade.php new file mode 100644 index 0000000..cce7064 --- /dev/null +++ b/resources/views/filament/pages/production-order-count.blade.php @@ -0,0 +1,14 @@ + +
+ {{-- Render the Select form fields --}} +
+ {{ $this->filtersForm($this->form) }} +
+ + {{-- Render the chart widget below the form --}} +
+ @livewire(\App\Filament\Widgets\ProductionOrderChart::class) +
+
+ +