- Remove unused FeaturesController (empty stubs, no routes) - Remove ConvertSpatialFile CLI command (unused; service used in LayerManager) - Remove MigrateGeojsonToFeatures CLI command (one-shot migration, not referenced) - Remove .claude/worktrees/ (11 old agent worktrees from June) - Apply Laravel Pint formatting across 219 files (style only, no functional changes) Tests: 101 passing (319 assertions) API routes: unchanged (8 routes intact)
127 lines
4.0 KiB
PHP
127 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Reports;
|
|
|
|
use App\DTO\ReportFilters;
|
|
use App\Models\Project;
|
|
use App\Services\ReportGenerator;
|
|
use Livewire\Component;
|
|
|
|
class ReportBuilder extends Component
|
|
{
|
|
public Project $project;
|
|
|
|
public array $filters = [
|
|
'date_from' => null,
|
|
'date_to' => null,
|
|
'entity_types' => ['phases', 'features', 'inspections', 'issues', 'tasks'],
|
|
'include_photos' => false,
|
|
'include_charts' => false,
|
|
'format' => 'html',
|
|
];
|
|
|
|
public bool $showPreview = false;
|
|
|
|
public ?array $previewData = null;
|
|
|
|
public function mount(Project $project)
|
|
{
|
|
$this->project = $project;
|
|
$this->authorizeAccess();
|
|
}
|
|
|
|
public function authorizeAccess(): void
|
|
{
|
|
$user = auth()->guard()->user();
|
|
if (! $user->can('manage all') && ! $this->project->users()->where('user_id', $user->id)->exists()) {
|
|
abort(403);
|
|
}
|
|
}
|
|
|
|
public function setDateRange(string $preset): void
|
|
{
|
|
$now = now();
|
|
match ($preset) {
|
|
'week' => [
|
|
$this->filters['date_from'] = $now->copy()->startOfWeek()->toDateString(),
|
|
$this->filters['date_to'] = $now->copy()->endOfWeek()->toDateString(),
|
|
],
|
|
'month' => [
|
|
$this->filters['date_from'] = $now->copy()->startOfMonth()->toDateString(),
|
|
$this->filters['date_to'] = $now->copy()->endOfMonth()->toDateString(),
|
|
],
|
|
'quarter' => [
|
|
$this->filters['date_from'] = $now->copy()->startOfQuarter()->toDateString(),
|
|
$this->filters['date_to'] = $now->copy()->endOfQuarter()->toDateString(),
|
|
],
|
|
'year' => [
|
|
$this->filters['date_from'] = $now->copy()->startOfYear()->toDateString(),
|
|
$this->filters['date_to'] = $now->copy()->endOfYear()->toDateString(),
|
|
],
|
|
};
|
|
}
|
|
|
|
public function clearDateRange(): void
|
|
{
|
|
$this->filters['date_from'] = null;
|
|
$this->filters['date_to'] = null;
|
|
}
|
|
|
|
public function generateReport()
|
|
{
|
|
$this->validate([
|
|
'filters.date_from' => 'nullable|date',
|
|
'filters.date_to' => 'nullable|date|after_or_equal:filters.date_from',
|
|
'filters.entity_types' => 'required|array|min:1',
|
|
'filters.format' => 'required|in:html,excel',
|
|
]);
|
|
|
|
$reportFilters = ReportFilters::fromRequest($this->filters);
|
|
$generator = new ReportGenerator($this->project, $reportFilters);
|
|
$data = $generator->generate();
|
|
|
|
if ($this->filters['format'] === 'excel') {
|
|
// Redirect to download route
|
|
return redirect()->route('reports.project.excel', [
|
|
'project' => $this->project,
|
|
...$reportFilters->toArray(),
|
|
]);
|
|
}
|
|
|
|
// For HTML, we'll render the complete report view
|
|
// The view will be returned by the controller
|
|
return $this->redirectRoute('reports.project.generate', [
|
|
'project' => $this->project,
|
|
...$reportFilters->toArray(),
|
|
]);
|
|
}
|
|
|
|
public function previewReport(): void
|
|
{
|
|
$this->validate([
|
|
'filters.date_from' => 'nullable|date',
|
|
'filters.date_to' => 'nullable|date|after_or_equal:filters.date_from',
|
|
'filters.entity_types' => 'required|array|min:1',
|
|
]);
|
|
|
|
$reportFilters = ReportFilters::fromRequest($this->filters);
|
|
$generator = new ReportGenerator($this->project, $reportFilters);
|
|
$this->previewData = $generator->generate();
|
|
$this->showPreview = true;
|
|
}
|
|
|
|
public function closePreview(): void
|
|
{
|
|
$this->showPreview = false;
|
|
$this->previewData = null;
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.reports.report-builder', [
|
|
'project' => $this->project,
|
|
'availableEntities' => (new ReportFilters)->getAvailableEntities(),
|
|
]);
|
|
}
|
|
}
|