delete(); WeeklyRoutePerformance::where('tenant_id', $tenantId)->delete(); MonthlyStoreSale::where('tenant_id', $tenantId)->delete(); $barangays = Barangay::limit(5)->get(); $routes = Route::where('tenant_id', $tenantId)->get(); $stores = PartnerStore::where('tenant_id', $tenantId)->get(); $dumpsite = Dumpsite::where('tenant_id', $tenantId)->first(); $driver = User::where('role', User::ROLE_DRIVER)->where('tenant_id', $tenantId)->first(); if ($barangays->isEmpty() || $routes->isEmpty() || $stores->isEmpty() || !$dumpsite || !$driver) { $this->command->warn('Prerequisites for ReportDataSeeder missing. Run SimulationContinuationSeeder first.'); return; } $this->seedDailyStats($tenantId, $barangays); $this->seedWeeklyPerformance($tenantId, $routes); $this->seedMonthlySales($tenantId, $stores); $this->seedDumpsiteReleases($tenantId, $dumpsite, $driver); $this->command->info('Report data seeded successfully!'); } private function seedDailyStats($tenantId, $barangays): void { $this->command->info('Seeding Daily Collection Stats...'); for ($i = 30; $i >= 0; $i--) { $date = Carbon::now()->subDays($i); foreach ($barangays as $barangay) { $baseScans = 150 + rand(-50, 100); $baseWeight = $baseScans * 5 + rand(-50, 50); DailyCollectionStat::withoutGlobalScopes()->updateOrCreate( ['date' => $date->toDateString(), 'barangay_id' => $barangay->id], [ 'tenant_id' => $tenantId, 'total_scans' => $baseScans, 'total_weight_kg' => $baseWeight, 'unique_households' => (int)($baseScans * 0.8), 'missed_pickups' => rand(0, 10), ] ); } } } private function seedWeeklyPerformance($tenantId, $routes): void { $this->command->info('Seeding Weekly Route Performance...'); for ($i = 8; $i >= 0; $i--) { $weekStart = Carbon::now()->subWeeks($i)->startOfWeek(); foreach ($routes as $route) { WeeklyRoutePerformance::withoutGlobalScopes()->updateOrCreate( ['week_start_date' => $weekStart->toDateString(), 'route_id' => $route->id], [ 'tenant_id' => $tenantId, 'on_time_rate_percent' => rand(85, 98), 'avg_trip_duration_minutes' => rand(150, 210), 'completion_rate_percent' => rand(95, 100), 'trips_count' => 6, ] ); } } } private function seedMonthlySales($tenantId, $stores): void { $this->command->info('Seeding Monthly Store Sales...'); for ($i = 6; $i >= 0; $i--) { $monthStart = Carbon::now()->subMonths($i)->startOfMonth(); foreach ($stores as $store) { $qty = 200 + rand(-50, 300); $retail = $qty * 1500; $commission = (int)($retail * ($store->commission_rate_percent / 100)); MonthlyStoreSale::withoutGlobalScopes()->updateOrCreate( ['month_start_date' => $monthStart->toDateString(), 'store_id' => $store->id], [ 'tenant_id' => $tenantId, 'total_quantity_sold' => $qty, 'total_retail_centavos' => $retail, 'total_commission_centavos' => $commission, ] ); } } } private function seedDumpsiteReleases($tenantId, $dumpsite, $driver): void { $this->command->info('Seeding Dumpsite Releases...'); for ($i = 20; $i >= 1; $i--) { $releasedAt = Carbon::now()->subDays($i)->setTime(11, 30); $trip = Trip::firstOrCreate( ['trip_number' => "HIST-TRIP-" . $releasedAt->format('Ymd')], [ 'uuid' => (string) Str::uuid(), 'tenant_id' => $tenantId, 'route_id' => Route::where('tenant_id', $tenantId)->first()->id, 'team_id' => 1, 'truck_id' => 1, 'scheduled_date' => $releasedAt->toDateString(), 'status' => Trip::STATUS_COMPLETED, 'actual_end_time' => $releasedAt, 'end_reason' => 'completed' ] ); DumpsiteRelease::updateOrCreate( ['tenant_id' => $tenantId, 'trip_id' => $trip->id], [ 'dumpsite_id' => $dumpsite->id, 'released_at' => $releasedAt, 'released_by_driver_id' => $driver->id, 'weight_kg' => 4500 + rand(-500, 500), 'waste_type_breakdown' => ['mixed' => 70, 'recyclable' => 20, 'organic' => 10], 'gate_pass_number' => "GP-" . strtoupper(Str::random(8)), 'dumpsite_attendant_name' => "Attendant " . rand(1, 5), 'coordinates_at_release' => new Point(6.1136, 125.1719, 4326), ] ); } } }