From 9985ed9e44c6fd86f3abe6d7384e02492b206e25 Mon Sep 17 00:00:00 2001 From: philipp lang Date: Mon, 29 Jan 2024 00:13:03 +0100 Subject: [PATCH] Add membership filter --- app/Member/FilterScope.php | 40 +++++++++++++++++++++++++--- app/Member/Member.php | 2 +- app/Member/MemberResource.php | 5 ++++ resources/js/views/member/VIndex.vue | 33 ++++++++++++++++++----- tests/EndToEnd/MemberIndexTest.php | 30 +++++++++++++++++++++ 5 files changed, 100 insertions(+), 10 deletions(-) diff --git a/app/Member/FilterScope.php b/app/Member/FilterScope.php index 3cb9ded7..8bfd5e18 100644 --- a/app/Member/FilterScope.php +++ b/app/Member/FilterScope.php @@ -23,10 +23,12 @@ class FilterScope extends Filter * @param array $groupIds * @param array $include * @param array $exclude + * @param array, subactivity_ids: array, activity_ids: array}> $memberships */ public function __construct( public bool $ausstand = false, public ?string $billKind = null, + public array $memberships = [], public array $activityIds = [], public array $subactivityIds = [], public ?string $search = '', @@ -73,13 +75,16 @@ class FilterScope extends Filter $filter->push($this->inExpression('memberships.subactivity_id', $this->subactivityIds)); } if ($this->subactivityIds && $this->activityIds) { - $combinations = collect($this->activityIds) - ->map(fn ($activityId) => collect($this->subactivityIds)->map(fn ($subactivityId) => $activityId . '|' . $subactivityId)) - ->flatten() + $combinations = $this->combinations($this->activityIds, $this->subactivityIds) + ->map(fn ($combination) => implode('|', $combination)) ->map(fn ($combination) => str($combination)->wrap('"')); $filter->push($this->inExpression('memberships.both', $combinations)); } + foreach ($this->memberships as $membership) { + $filter->push($this->inExpression('memberships.with_group', $this->possibleValuesForMembership($membership)->map(fn ($value) => str($value)->wrap('"')))); + } + if (count($this->exclude)) { $filter->push($this->notInExpression('id', $this->exclude)); } @@ -127,4 +132,33 @@ class FilterScope extends Filter return "$key NOT IN [{$valueString}]"; } + + protected function possibleValuesForMembership(array $membership): Collection + { + return $this->combinations($membership['group_ids'], $membership['activity_ids'], $membership['subactivity_ids']) + ->map(fn ($combination) => collect($combination)->implode('|')); + } + + /** + * @return Collection + */ + protected function combinations(...$parts): Collection + { + $firstPart = array_shift($parts); + $otherParts = $parts; + + if (!count($otherParts)) { + return collect(array_map(fn ($p) => [$p], $firstPart)); + } + + /** @var Collection */ + $results = collect([]); + foreach ($firstPart as $firstPartSegment) { + foreach ($this->combinations(...$otherParts) as $combination) { + $results->push([$firstPartSegment, ...$combination]); + } + } + + return $results; + } } diff --git a/app/Member/Member.php b/app/Member/Member.php index 3320b758..a8f4db4d 100644 --- a/app/Member/Member.php +++ b/app/Member/Member.php @@ -502,7 +502,7 @@ class Member extends Model implements Geolocatable 'bill_kind' => $this->bill_kind?->value, 'group_id' => $this->group->id, 'memberships' => $this->memberships()->active()->get() - ->map(fn ($membership) => [...$membership->only('activity_id', 'subactivity_id'), 'both' => $membership->activity_id . '|' . $membership->subactivity_id]), + ->map(fn ($membership) => [...$membership->only('activity_id', 'subactivity_id'), 'both' => $membership->activity_id . '|' . $membership->subactivity_id, 'with_group' => $membership->group_id . '|' . $membership->activity_id . '|' . $membership->subactivity_id]), ]; } } diff --git a/app/Member/MemberResource.php b/app/Member/MemberResource.php index 3ebd946b..6cee1095 100644 --- a/app/Member/MemberResource.php +++ b/app/Member/MemberResource.php @@ -157,6 +157,11 @@ class MemberResource extends JsonResource 'index' => route('member.index'), 'create' => route('member.create'), ], + 'default_membership_filter' => [ + 'group_ids' => [], + 'activity_ids' => [], + 'subactivity_ids' => [] + ], ]; } diff --git a/resources/js/views/member/VIndex.vue b/resources/js/views/member/VIndex.vue index acf86dd5..b1ed276f 100644 --- a/resources/js/views/member/VIndex.vue +++ b/resources/js/views/member/VIndex.vue @@ -23,6 +23,28 @@ + + +
+ + + +
+ +
@@ -34,12 +56,10 @@ - - +