Files
fotospiel-app/app/Services/Tenant/DashboardSummaryService.php

76 lines
2.5 KiB
PHP

<?php
namespace App\Services\Tenant;
use App\Models\Event;
use App\Models\Photo;
use App\Models\Tenant;
use App\Models\TenantPackage;
use Illuminate\Support\Carbon;
class DashboardSummaryService
{
public function build(Tenant $tenant): array
{
$eventsQuery = Event::query()
->where('tenant_id', $tenant->getKey());
$totalEvents = (clone $eventsQuery)->count();
$activeEvents = (clone $eventsQuery)
->where(static function ($query) {
$query->where('is_active', true)
->orWhere('status', 'published');
})
->count();
$publishedEvents = (clone $eventsQuery)
->where('status', 'published')
->count();
$eventsWithTasks = (clone $eventsQuery)
->whereHas('tasks')
->count();
$upcomingEvents = (clone $eventsQuery)
->whereDate('date', '>=', Carbon::now()->startOfDay())
->count();
$newPhotos = Photo::query()
->whereHas('event', static function ($query) use ($tenant) {
$query->where('tenant_id', $tenant->getKey());
})
->where('created_at', '>=', Carbon::now()->subDays(7))
->count();
/** @var TenantPackage|null $activePackage */
$activePackage = $tenant->tenantPackages()
->with('package')
->where('active', true)
->orderByDesc('expires_at')
->orderByDesc('purchased_at')
->first();
return [
'total_events' => $totalEvents,
'active_events' => $activeEvents,
'published_events' => $publishedEvents,
'events_with_tasks' => $eventsWithTasks,
'upcoming_events' => $upcomingEvents,
'new_photos' => $newPhotos,
'task_progress' => $totalEvents > 0
? (int) round(($eventsWithTasks / $totalEvents) * 100)
: 0,
'credit_balance' => $tenant->event_credits_balance ?? null,
'active_package' => $activePackage ? [
'name' => $activePackage->package?->getNameForLocale(app()->getLocale())
?? $activePackage->package?->name
?? '',
'expires_at' => optional($activePackage->expires_at)->toIso8601String(),
'remaining_events' => $activePackage->remaining_events ?? null,
'price' => $activePackage->price !== null ? (float) $activePackage->price : null,
] : null,
];
}
}