|
10 | 10 | use App\Enums\Weekday; |
11 | 11 | use App\Models\Client; |
12 | 12 | use App\Models\Project; |
| 13 | +use App\Models\Tag; |
13 | 14 | use App\Models\Task; |
14 | 15 | use App\Models\TimeEntry; |
15 | 16 | use App\Models\User; |
16 | 17 | use Carbon\CarbonTimeZone; |
17 | 18 | use Illuminate\Database\Eloquent\Builder; |
18 | 19 | use Illuminate\Support\Carbon; |
19 | 20 | use Illuminate\Support\Collection; |
| 21 | +use Illuminate\Support\Facades\DB; |
20 | 22 | use Illuminate\Support\Facades\Log; |
21 | 23 |
|
22 | 24 | class TimeEntryAggregationService |
@@ -48,6 +50,10 @@ public function getAggregatedTimeEntries(Builder $timeEntriesQuery, ?TimeEntryAg |
48 | 50 | $group1Select = null; |
49 | 51 | $group2Select = null; |
50 | 52 | $groupBy = null; |
| 53 | + // If any grouping is by tag, expand rows per tag via CROSS JOIN LATERAL on the JSONB array |
| 54 | + if (($group1Type === TimeEntryAggregationType::Tag) || ($group2Type === TimeEntryAggregationType::Tag)) { |
| 55 | + $timeEntriesQuery->crossJoin(DB::raw("LATERAL jsonb_array_elements_text(coalesce(tags, '[]'::jsonb)) as tag(tag)")); |
| 56 | + } |
51 | 57 | if ($group1Type !== null) { |
52 | 58 | $group1Select = $this->getGroupByQuery($group1Type, $timezone, $startOfWeek); |
53 | 59 | $groupBy = ['group_1']; |
@@ -294,6 +300,17 @@ private function loadDescriptorsMap(array $keys, TimeEntryAggregationType $type) |
294 | 300 | 'color' => null, |
295 | 301 | ]; |
296 | 302 | } |
| 303 | + } elseif ($type === TimeEntryAggregationType::Tag) { |
| 304 | + $tags = Tag::query() |
| 305 | + ->whereIn('id', $keys) |
| 306 | + ->select('id', 'name') |
| 307 | + ->get(); |
| 308 | + foreach ($tags as $tag) { |
| 309 | + $descriptorMap[$tag->id] = [ |
| 310 | + 'description' => $tag->name, |
| 311 | + 'color' => null, |
| 312 | + ]; |
| 313 | + } |
297 | 314 | } |
298 | 315 |
|
299 | 316 | return $descriptorMap; |
@@ -436,6 +453,8 @@ private function getGroupByQuery(TimeEntryAggregationType $group, string $timezo |
436 | 453 | return 'billable'; |
437 | 454 | } elseif ($group === TimeEntryAggregationType::Description) { |
438 | 455 | return 'description'; |
| 456 | + } elseif ($group === TimeEntryAggregationType::Tag) { |
| 457 | + return 'tag'; |
439 | 458 | } |
440 | 459 | } |
441 | 460 |
|
|
0 commit comments