<?php
 namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Http\Requests\Admin\PreviewCustomReportRequest; use App\Http\Requests\Admin\StoreCustomReportRequest; use App\Http\Requests\Admin\UpdateCustomReportRequest; use App\Models\CustomReport; use App\Services\Reports\CsvExporter; use App\Services\Reports\Exceptions\InvalidIrException; use App\Services\Reports\ReportCompiler; use App\Services\Reports\ReportExecutor; use App\Services\Reports\SchemaIntrospector; use App\Traits\LogsAdminActivity; use Illuminate\Support\Facades\Auth; class CustomReportController extends Controller { use LogsAdminActivity; public function __construct( protected SchemaIntrospector $schema, protected ReportCompiler $compiler, protected ReportExecutor $executor, protected CsvExporter $exporter, ) {} public function index() { $this->authorize('viewAny', CustomReport::class); return view('admin.reports.custom.index'); } public function create() { $this->authorize('create', CustomReport::class); return view('admin.reports.custom.builder', [ 'report' => null, 'mode' => 'create', ]); } public function store(StoreCustomReportRequest $request) { $data = $request->validated(); $data['owner_admin_id'] = Auth::guard('admin')->id(); try { $this->compiler->compile($data['ir']); } catch (InvalidIrException $e) { return back()->withInput()->withErrors(['ir' => $e->getMessage()]); } $report = CustomReport::create($data); $this->logCreated(model: $report, description: "Created custom report #{$report->id} - {$report->name}"); return redirect()->route('admin.reports.custom.show', $report) ->with('success', __('admin/reports.custom_report_created')); } public function show(CustomReport $report) { $this->authorize('view', $report); return view('admin.reports.custom.show', compact('report')); } public function edit(CustomReport $report) { $this->authorize('update', $report); return view('admin.reports.custom.builder', [ 'report' => $report, 'mode' => 'edit', ]); } public function update(UpdateCustomReportRequest $request, CustomReport $report) { $this->authorize('update', $report); $data = $request->validated(); try { $this->compiler->compile($data['ir']); } catch (InvalidIrException $e) { return back()->withInput()->withErrors(['ir' => $e->getMessage()]); } $report->update($data); $this->logUpdated(model: $report, description: "Updated custom report #{$report->id}"); return redirect()->route('admin.reports.custom.show', $report) ->with('success', __('admin/reports.custom_report_updated')); } public function destroy(CustomReport $report) { $this->authorize('delete', $report); $this->logDeleted(model: $report, description: "Deleted custom report #{$report->id}"); $report->delete(); return redirect()->route('admin.reports.custom.index') ->with('success', __('admin/reports.custom_report_deleted')); } public function togglePublic(CustomReport $report) { $this->authorize('togglePublic', $report); $report->update(['is_public' => ! $report->is_public]); $this->logUpdated(model: $report, description: "Toggled public on report #{$report->id} to " . ($report->is_public ? 'public' : 'private')); return back()->with('success', __('admin/reports.public_toggled')); } public function preview(PreviewCustomReportRequest $request) { try { $rows = $this->executor->preview($request->input('ir')); return response()->json([ 'success' => true, 'rows' => $rows, 'count' => count($rows), ]); } catch (InvalidIrException $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage(), ], 422); } catch (\Throwable $e) { return response()->json([ 'success' => false, 'error' => 'Query failed: ' . $e->getMessage(), ], 500); } } public function export(CustomReport $report) { $this->authorize('view', $report); if (! request()->user('admin')?->can('export custom reports')) { abort(403); } return $this->exporter->streamResponse($report); } } 