> */ private array $types = [ BillType::class, RememberType::class, ]; /** * @return Collection */ public function getTypes(): Collection { return collect(array_map(fn ($classString) => new $classString(collect()), $this->types)); } public function fromSingleRequest(string $type, Member $member): ?LetterRepository { $members = $this->singleMemberCollection($member, $type); if ($members->isEmpty()) { return null; } $repo = $this->resolve($type, $members); $firstMember = $members->first()->first(); return $repo->setFilename( Str::slug("{$repo->getSubject()} für {$firstMember->lastname}"), ); } public function forAll(string $type, string $billKind): ?PdfRepository { $members = $this->toMemberGroup($this->allMemberCollection($type, $billKind)); if ($members->isEmpty()) { return null; } return $this->resolve($type, $members)->setFilename('alle-rechnungen'); } public function repoCollection(string $type, string $billKind): Collection { $members = $this->toMemberGroup($this->allMemberCollection($type, $billKind)); return $members->map(function (Collection $members) use ($type) { $repo = $this->resolve($type, collect([$members])); return $repo->setFilename(Str::slug("{$repo->getSubject()} für {$members->first()->lastname}")); }); } public function afterSingle(LetterRepository $repo): void { foreach ($repo->allPayments() as $payment) { $repo->afterSingle($payment); } } public function afterAll(string $type, string $billKind): void { $members = $this->allMemberCollection($type, $billKind); $repo = $this->resolve($type, $this->toMemberGroup($members)); $this->afterSingle($repo); } public function singleMemberCollection(Member $member, string $type): Collection { $members = Member::where($member->only(['lastname', 'address', 'zip', 'location'])) ->get() ->filter(fn (Member $member) => app($type)->createable($member)); return $this->toMemberGroup($members); } private function allMemberCollection(string $type, string $billKind): Collection { return Member::whereHas('billKind', fn (Builder $q) => $q->where('name', $billKind)) ->get() ->filter(fn (Member $member) => app($type)->createable($member)); } private function resolve(string $kind, Collection $members): LetterRepository { return new $kind($members); } private function toMemberGroup(Collection $members): Collection { return $members->groupBy( fn ($member) => Str::slug( "{$member->lastname}{$member->address}{$member->zip}{$member->location}", ), ); } }