Change logic of tags_ids filter from AND to OR

This commit is contained in:
Constantin Graf
2024-11-08 12:11:16 +01:00
committed by Constantin Graf
parent 45daeead61
commit 4b622afcfc
6 changed files with 53 additions and 5 deletions

View File

@@ -108,7 +108,7 @@ class TimeEntryAggregateExportRequest extends FormRequest
return $builder->whereBelongsTo($this->organization, 'organization');
})->uuid(),
],
// Filter by tag IDs, tag IDs are AND combined
// Filter by tag IDs, tag IDs are OR combined
'tag_ids' => [
'array',
'min:1',

View File

@@ -95,7 +95,7 @@ class TimeEntryAggregateRequest extends FormRequest
return $builder->whereBelongsTo($this->organization, 'organization');
})->uuid(),
],
// Filter by tag IDs, tag IDs are AND combined
// Filter by tag IDs, tag IDs are OR combined
'tag_ids' => [
'array',
'min:1',

View File

@@ -68,7 +68,7 @@ class TimeEntryIndexExportRequest extends TimeEntryIndexRequest
return $builder->whereBelongsTo($this->organization, 'organization');
}),
],
// Filter by tag IDs, tag IDs are AND combined
// Filter by tag IDs, tag IDs are OR combined
'tag_ids' => [
'array',
'min:1',

View File

@@ -72,7 +72,7 @@ class TimeEntryIndexRequest extends FormRequest
return $builder->whereBelongsTo($this->organization, 'organization');
})->uuid(),
],
// Filter by tag IDs, tag IDs are AND combined
// Filter by tag IDs, tag IDs are OR combined
'tag_ids' => [
'array',
'min:1',

View File

@@ -133,7 +133,11 @@ class TimeEntryFilter
if ($tagIds === null) {
return $this;
}
$this->builder->whereJsonContains('tags', $tagIds);
$this->builder->where(function (Builder $builder) use ($tagIds): void {
foreach ($tagIds as $tagId) {
$builder->orWhereJsonContains('tags', $tagId);
}
});
return $this;
}

View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Service;
use App\Models\Tag;
use App\Models\TimeEntry;
use App\Service\TimeEntryFilter;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use Tests\TestCaseWithDatabase;
#[CoversClass(TimeEntryFilter::class)]
#[UsesClass(TimeEntryFilter::class)]
class TimeEntryFilterTest extends TestCaseWithDatabase
{
public function test_add_tag_ids_filter_is_or(): void
{
// Arrange
$builder = TimeEntry::query();
$filter = new TimeEntryFilter($builder);
$timEntryNoTag = TimeEntry::factory()->create();
$tag1 = Tag::factory()->create();
$timeEntryWithTag1 = TimeEntry::factory()->create([
'tags' => [$tag1->getKey()],
]);
$tag2 = Tag::factory()->create();
$timeEntryWithTag2 = TimeEntry::factory()->create([
'tags' => [$tag2->getKey()],
]);
$timeEntryWithAllTags = TimeEntry::factory()->create([
'tags' => [$tag1->getKey(), $tag2->getKey()],
]);
// Act
$filter->addTagIdsFilter([$tag1->getKey(), $tag2->getKey()]);
// Assert
$timeEntries = $builder->get();
$this->assertCount(3, $timeEntries);
}
}