'from', 'type' => 'date', 'label' => 'Od', 'nullable' => true], ['key' => 'to', 'type' => 'date', 'label' => 'Do', 'nullable' => true], ['key' => 'period', 'type' => 'string', 'label' => 'Obdobje (day|week|month)', 'default' => 'day'], ]; } public function columns(): array { return [ ['key' => 'period', 'label' => 'Obdobje'], ['key' => 'activities_count', 'label' => 'Št. aktivnosti'], ]; } public function query(array $filters): Builder { $periodRaw = $filters['period'] ?? 'day'; $period = in_array($periodRaw, ['day', 'week', 'month'], true) ? $periodRaw : 'day'; $driver = DB::getDriverName(); // Build database-compatible period expressions if ($driver === 'sqlite') { if ($period === 'day') { // Use string slice to avoid timezone conversion differences in SQLite $selectExpr = DB::raw('SUBSTR(activities.created_at, 1, 10) as period'); $groupExpr = DB::raw('SUBSTR(activities.created_at, 1, 10)'); $orderExpr = DB::raw('SUBSTR(activities.created_at, 1, 10)'); } elseif ($period === 'month') { $selectExpr = DB::raw("strftime('%Y-%m-01', activities.created_at) as period"); $groupExpr = DB::raw("strftime('%Y-%m-01', activities.created_at)"); $orderExpr = DB::raw("strftime('%Y-%m-01', activities.created_at)"); } else { // week $selectExpr = DB::raw("strftime('%Y-%W', activities.created_at) as period"); $groupExpr = DB::raw("strftime('%Y-%W', activities.created_at)"); $orderExpr = DB::raw("strftime('%Y-%W', activities.created_at)"); } } elseif ($driver === 'mysql') { if ($period === 'day') { $selectExpr = DB::raw('DATE(activities.created_at) as period'); $groupExpr = DB::raw('DATE(activities.created_at)'); $orderExpr = DB::raw('DATE(activities.created_at)'); } elseif ($period === 'month') { $selectExpr = DB::raw("DATE_FORMAT(activities.created_at, '%Y-%m-01') as period"); $groupExpr = DB::raw("DATE_FORMAT(activities.created_at, '%Y-%m-01')"); $orderExpr = DB::raw("DATE_FORMAT(activities.created_at, '%Y-%m-01')"); } else { // week // ISO week-year-week number for grouping; adequate for summary grouping $selectExpr = DB::raw("DATE_FORMAT(activities.created_at, '%x-%v') as period"); $groupExpr = DB::raw("DATE_FORMAT(activities.created_at, '%x-%v')"); $orderExpr = DB::raw("DATE_FORMAT(activities.created_at, '%x-%v')"); } } else { // postgres and others supporting date_trunc $selectExpr = DB::raw("date_trunc('".$period."', activities.created_at) as period"); $groupExpr = DB::raw("date_trunc('".$period."', activities.created_at)"); $orderExpr = DB::raw("date_trunc('".$period."', activities.created_at)"); } return Activity::query() ->when(! empty($filters['from']), fn ($q) => $q->whereDate('activities.created_at', '>=', $filters['from'])) ->when(! empty($filters['to']), fn ($q) => $q->whereDate('activities.created_at', '<=', $filters['to'])) ->groupBy($groupExpr) ->orderBy($orderExpr) ->select($selectExpr) ->selectRaw('COUNT(*) as activities_count'); } }