96 lines
4.1 KiB
PHP
96 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Reports;
|
|
|
|
use App\Models\Activity;
|
|
use App\Reports\Contracts\Report;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class ActivitiesPerPeriodReport extends BaseEloquentReport implements Report
|
|
{
|
|
public function slug(): string
|
|
{
|
|
return 'activities-per-period';
|
|
}
|
|
|
|
public function name(): string
|
|
{
|
|
return 'Aktivnosti po obdobjih';
|
|
}
|
|
|
|
public function description(): ?string
|
|
{
|
|
return 'Seštevek aktivnosti po dneh/tednih/mesecih v obdobju.';
|
|
}
|
|
|
|
public function inputs(): array
|
|
{
|
|
return [
|
|
['key' => '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');
|
|
}
|
|
}
|