startOfMonth(); $endDate = $endDate ?? now(); $job = IhExportJob::create([ 'business_id' => $businessId, 'dataset' => 'executive_cockpit', 'format' => $format, 'status' => 'processing', ]); try { $payload = $this->buildPayload($businessId, $startDate, $endDate); $filePath = $this->writeExportFile($businessId, $job->id, $format, $payload); $job->markCompleted($filePath); ExecutiveCockpitExported::dispatch($businessId, $payload, $job->id); IntegrationExportCompleted::dispatch($businessId, 'executive_cockpit', $format, $filePath, $job->id); return $job->fresh(); } catch (\Throwable $e) { $job->markFailed(); throw $e; } } public function buildPayload(int $businessId, Carbon $startDate, Carbon $endDate): array { if (class_exists(\Modules\ManagementTools\Services\ExecutiveCockpitService::class) && \Module::has('ManagementTools') && \Module::isEnabled('ManagementTools')) { $cockpit = app(\Modules\ManagementTools\Services\ExecutiveCockpitService::class); return $cockpit->build($businessId, $startDate, $endDate); } $filters = [ 'start_date' => $startDate->toDateString(), 'end_date' => $endDate->toDateString(), ]; return [ 'range' => ['start' => $startDate, 'end' => $endDate], 'sales_summary' => $this->odataExportService->dataset($businessId, 'sales_summary', $filters), 'inventory_snapshot' => $this->odataExportService->dataset($businessId, 'inventory_snapshot', $filters), 'production_kpis' => $this->odataExportService->dataset($businessId, 'production_kpis', $filters), 'maintenance_kpis' => $this->odataExportService->dataset($businessId, 'maintenance_kpis', $filters), 'qms_kpis' => $this->odataExportService->dataset($businessId, 'qms_kpis', $filters), 'exported_at' => now()->toIso8601String(), ]; } protected function writeExportFile(int $businessId, int $jobId, string $format, array $payload): string { $directory = "integrationhub/exports/{$businessId}"; $filename = "executive_cockpit_{$jobId}_".now()->format('Ymd_His'); if ($format === 'json') { $path = "{$directory}/{$filename}.json"; Storage::disk('local')->put($path, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); return $path; } if ($format === 'csv') { $path = "{$directory}/{$filename}.csv"; $rows = $this->flattenForCsv($payload); $handle = fopen('php://temp', 'r+'); if (! empty($rows)) { fputcsv($handle, array_keys($rows[0])); foreach ($rows as $row) { fputcsv($handle, $row); } } rewind($handle); Storage::disk('local')->put($path, stream_get_contents($handle)); fclose($handle); return $path; } $path = "{$directory}/{$filename}.json"; Storage::disk('local')->put($path, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); return $path; } protected function flattenForCsv(array $payload): array { $rows = []; foreach (['sales_summary', 'inventory_snapshot'] as $key) { if (! isset($payload[$key]['value']) || ! is_array($payload[$key]['value'])) { continue; } foreach ($payload[$key]['value'] as $item) { $rows[] = array_merge(['section' => $key], (array) $item); } } return $rows; } }