|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace App\GraphQL\Queries; |
| 4 | + |
| 5 | +use App\Helper; |
| 6 | +use App\Models\Activity; |
| 7 | +use App\Models\Project; |
| 8 | +use Illuminate\Pagination\LengthAwarePaginator; |
| 9 | +use Nuwave\Lighthouse\Execution\ResolveInfo; |
| 10 | +use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; |
| 11 | + |
| 12 | +final class ApprovedActivities { |
| 13 | + public function __invoke($root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo): LengthAwarePaginator { |
| 14 | + $perPage = $args['first'] ?? 25; |
| 15 | + $currentPage = $args['page'] ?? 1; |
| 16 | + $queryLimit = $perPage * $currentPage; |
| 17 | + |
| 18 | + $projectsQuery = Project::where('closure_approved_status', 1) |
| 19 | + ->whereBetween('closure_approved_at', [$args['from'], $args['until']]); |
| 20 | + $projects = $projectsQuery->with([ |
| 21 | + 'participants' => fn($query) => $query->where('approve_status', '>=', 1), |
| 22 | + 'participants.user', |
| 23 | + 'department', |
| 24 | + ]) |
| 25 | + ->select([ |
| 26 | + 'id', 'year', 'number', 'name', 'department_id', 'period_start', 'period_end', 'duration', 'closure_approved_at', |
| 27 | + 'closure_approved_status', 'advisor', |
| 28 | + ]) |
| 29 | + ->orderBy('closure_approved_at', 'desc') |
| 30 | + ->take($queryLimit)->get() |
| 31 | + ->map(fn($project) => [ |
| 32 | + 'identifier' => $project->year.'-'.$project->number, |
| 33 | + 'project_id' => $project->id, |
| 34 | + 'name' => $project->name, |
| 35 | + 'organization' => Helper::formatDepartmentName($project->department?->name ?? ''), |
| 36 | + 'period_start' => $project->period_start?->addYears(543)->toDateTimeString(), |
| 37 | + 'period_end' => $project->period_end?->addYears(543)->toDateTimeString(), |
| 38 | + 'duration' => $project->duration, |
| 39 | + 'approved_status' => $project->closure_approved_status, |
| 40 | + 'approved_at' => $project->closure_approved_at, |
| 41 | + 'advisor' => $project->advisor, |
| 42 | + 'participants' => $project->participants, |
| 43 | + ])->toBase(); |
| 44 | + // Note that participant approve_status is not set in Activity |
| 45 | + $activitiesQuery = Activity::with(['participants', 'participants.user']) |
| 46 | + ->whereBetween('updated_at', [$args['from'], $args['until']]); |
| 47 | + $activities = $activitiesQuery->orderBy('updated_at', 'desc') |
| 48 | + ->take($queryLimit)->get() |
| 49 | + ->map(fn($activity) => [ |
| 50 | + 'identifier' => 'A'.$activity->id, |
| 51 | + 'activity_id' => $activity->id, |
| 52 | + 'name' => $activity->name, |
| 53 | + 'organization' => $activity->organization, |
| 54 | + 'period_start' => $activity->period_start?->toDateTimeString(), |
| 55 | + 'period_end' => $activity->period_end?->toDateTimeString(), |
| 56 | + 'duration' => $activity->duration, |
| 57 | + 'approved_at' => $activity->updated_at, |
| 58 | + 'participants' => $activity->participants, |
| 59 | + ]); |
| 60 | + $merged = $projects->merge($activities)->sortByDesc('approved_at'); |
| 61 | + |
| 62 | + return new LengthAwarePaginator( |
| 63 | + items: $merged->chunk($perPage)[$currentPage - 1] ?? [], |
| 64 | + total: ($projects->count() == $queryLimit or $activities->count() == $queryLimit) |
| 65 | + ? ($projectsQuery->count() + $activitiesQuery->count()) // count directly from database |
| 66 | + : $merged->count(), |
| 67 | + perPage: $perPage, |
| 68 | + currentPage: $currentPage |
| 69 | + ); |
| 70 | + } |
| 71 | +} |
0 commit comments