<?php
 namespace App\Reports; abstract class BaseReport implements ReportInterface { protected array $filters = []; protected array $data = []; protected ?array $chartData = null; public function process(array $filters = []): array { $this->filters = $filters; $this->data = $this->getData($filters); if ($this->hasChart()) { $this->chartData = $this->getChartData($filters); } return [ 'success' => true, 'data' => $this->data, 'columns' => $this->getColumns(), 'filters' => $this->getFilters(), 'chart' => $this->chartData ? [ 'type' => $this->getChartType(), 'data' => $this->chartData, ] : null, 'summary' => $this->getSummary(), 'meta' => [ 'name' => $this->getName(), 'description' => $this->getDescription(), 'category' => $this->getCategory(), 'icon' => $this->getIcon(), 'has_chart' => $this->hasChart(), ], ]; } protected function getSummary(): array { return [ 'total_records' => count($this->data), 'generated_at' => now()->toISOString(), 'filters_applied' => $this->filters, ]; } protected function applyDateFilter($query, string $dateField = 'created_at'): void { if (isset($this->filters['start_date'])) { $query->where($dateField, '>=', $this->filters['start_date']); } if (isset($this->filters['end_date'])) { $query->where($dateField, '<=', $this->filters['end_date']); } } protected function applyPeriodFilter($query, string $dateField = 'created_at'): void { $period = $this->filters['period'] ?? 'monthly'; switch ($period) { case 'daily': $query->selectRaw("DATE($dateField) as period, COUNT(*) as count") ->groupBy('period') ->orderBy('period'); break; case 'weekly': $query->selectRaw("YEARWEEK($dateField) as period, COUNT(*) as count") ->groupBy('period') ->orderBy('period'); break; case 'monthly': $query->selectRaw("DATE_FORMAT($dateField, '%Y-%m') as period, COUNT(*) as count") ->groupBy('period') ->orderBy('period'); break; case 'quarterly': $query->selectRaw("CONCAT(YEAR($dateField), '-Q', QUARTER($dateField)) as period, COUNT(*) as count") ->groupBy('period') ->orderBy('period'); break; case 'yearly': $query->selectRaw("YEAR($dateField) as period, COUNT(*) as count") ->groupBy('period') ->orderBy('period'); break; } } public function getColumns(): array { return [ 'id' => [ 'title' => __('admin/reports.base_column_id'), 'type' => 'number', 'sortable' => true, ], 'created_at' => [ 'title' => __('admin/reports.base_column_created_at'), 'type' => 'date', 'sortable' => true, ], ]; } public function getFilters(): array { return [ 'start_date' => [ 'type' => 'date', 'label' => __('admin/reports.base_filter_start_date'), 'required' => false, 'default' => now()->subMonth()->format('Y-m-d'), ], 'end_date' => [ 'type' => 'date', 'label' => __('admin/reports.base_filter_end_date'), 'required' => false, 'default' => now()->format('Y-m-d'), ], 'period' => [ 'type' => 'select', 'label' => __('admin/reports.base_filter_period'), 'required' => false, 'options' => [ 'daily' => __('admin/reports.base_period_daily'), 'weekly' => __('admin/reports.base_period_weekly'), 'monthly' => __('admin/reports.base_period_monthly'), 'yearly' => __('admin/reports.base_period_yearly'), ], 'default' => 'monthly', ], ]; } public function getDefaultFilters(): array { return [ 'start_date' => now()->subMonth()->format('Y-m-d'), 'end_date' => now()->format('Y-m-d'), 'period' => 'monthly', ]; } public function validateFilters(array $filters): array { $rules = [ 'start_date' => 'nullable|date', 'end_date' => 'nullable|date|after_or_equal:start_date', 'period' => 'nullable|in:daily,weekly,monthly,quarterly,yearly', 'year' => 'nullable|integer|min:2020|max:'.(date('Y') + 1), 'month' => 'nullable|integer|min:1|max:12', 'cohort_size' => 'nullable|integer|min:1|max:365', 'currency' => 'nullable|string|in:all,TRY,USD,EUR', 'product_category' => 'nullable|string', 'suspension_reason' => 'nullable|string', 'limit' => 'nullable|integer|min:1|max:100', 'country' => 'nullable|string', 'source' => 'nullable|string', 'payment_method' => 'nullable|string', 'min_mrr' => 'nullable|numeric|min:0', 'max_mrr' => 'nullable|numeric|min:0', 'client_id' => 'nullable|integer|exists:clients,id', 'transaction_type' => 'nullable|string', 'min_clients' => 'nullable|integer|min:0', 'min_services' => 'nullable|integer|min:0', 'min_registrations' => 'nullable|integer|min:0', ]; $validator = validator($filters, $rules); if ($validator->fails()) { throw new \InvalidArgumentException($validator->errors()->first()); } return $filters; } } 