middleware('active.account'); } public function teaser($slug) { $incentive = Incentive::where('slug', $slug) ->where('status', '!=', 0) ->firstOrFail(); $user = Auth::user(); $participant = IncentiveParticipant::where('incentive_id', $incentive->id) ->where('user_id', $user->id) ->first(); $galleryImages = $this->collectGalleryImages($incentive); return view('user.incentive.teaser', [ 'incentive' => $incentive, 'participant' => $participant, 'galleryImages' => $galleryImages, ]); } public function show($slug) { $incentive = Incentive::where('slug', $slug) ->where('status', '!=', 0) // not draft ->firstOrFail(); $user = Auth::user(); $participant = IncentiveParticipant::where('incentive_id', $incentive->id) ->where('user_id', $user->id) ->first(); $ranking = IncentiveParticipant::where('incentive_id', $incentive->id) ->withRankingActivity() ->with('user', 'user.account') ->orderByIncentiveLeaderboard() ->paginate(100); $participateHasTrackableAbos = false; if (! $participant?->accepted_terms_at) { $participateHasTrackableAbos = $this->userHasTrackableAbosForIncentive($user, $incentive); } return view('user.incentive.show', [ 'incentive' => $incentive, 'participant' => $participant, 'hasConfirmedParticipation' => $participant && $participant->accepted_terms_at !== null, 'ranking' => $ranking, 'participateHasTrackableAbos' => $participateHasTrackableAbos, 'isVipView' => $user->isVIP(), ]); } public function participate($slug) { $incentive = Incentive::where('slug', $slug) ->active() ->firstOrFail(); if (! Request::has('accept_terms')) { \Session()->flash('alert-error', __('incentive.terms_required')); return redirect(route('user_incentive_show', [$slug])); } $user = Auth::user(); $participant = IncentiveParticipant::firstOrCreate( [ 'incentive_id' => $incentive->id, 'user_id' => $user->id, ], [ 'accepted_terms_at' => null, ] ); if ($participant->accepted_terms_at !== null) { \Session()->flash('alert-info', __('incentive.already_participating')); return redirect(route('user_incentive_show', [$slug])); } $participant->accepted_terms_at = Carbon::now(); $participant->save(); $repair = app(IncentivePointsLogRepairService::class); $repair->syncMissingTrackingAbos($participant); $repair->syncMissingSalesVolumeLogs($participant); $participant->refresh()->recalculateFromTrackingTables()->save(); IncentiveTracker::updateRanking($incentive); \Session()->flash('alert-success', __('incentive.participation_confirmed')); return redirect(route('user_incentive_show', [$slug])); } public function details($slug) { $incentive = Incentive::where('slug', $slug) ->where('status', '!=', 0) ->firstOrFail(); $user = Auth::user(); $participant = IncentiveParticipant::with('incentive', 'user', 'user.account') ->where('incentive_id', $incentive->id) ->where('user_id', $user->id) ->firstOrFail(); if ($participant->accepted_terms_at === null) { \Session()->flash('alert-info', __('incentive.details_requires_confirmation')); return redirect(route('user_incentive_show', [$slug])); } $data = AdminIncentiveController::buildParticipantDetailData($participant); return view('user.incentive.details', $data); } /** * Sammelt alle verfuegbaren Galerie-Bilder aus public/img/incentive/ * (ohne das Hauptbild, das bereits als Hero verwendet wird). * * @return list */ private function collectGalleryImages(Incentive $incentive): array { $dir = public_path('img/incentive'); if (! is_dir($dir)) { return []; } $files = glob($dir.'/*.{jpg,jpeg,png,webp}', GLOB_BRACE) ?: []; $images = []; foreach ($files as $file) { $basename = basename($file); $images[] = 'img/incentive/'.$basename; } sort($images); return $images; } /** * Hinweis auf der Teilnehmen-Karte: Es gibt bereits ein Eigenabo oder ein Kundenabo im Qualifikationszeitraum. */ private function userHasTrackableAbosForIncentive(User $user, Incentive $incentive): bool { $qualEnd = $incentive->qualification_end->copy()->endOfDay(); $hasOwnActiveAbo = UserAbo::query() ->where('user_id', $user->id) ->where('is_for', 'me') ->where('status', 2) ->exists(); $hasCustomerAboInQualification = UserAbo::query() ->where('member_id', $user->id) ->where('is_for', 'ot') ->where('status', 2) ->whereBetween('created_at', [ $incentive->qualification_start, $qualEnd, ]) ->exists(); return $hasOwnActiveAbo || $hasCustomerAboInQualification; } }