10.April 2026
This commit is contained in:
parent
a00c42e770
commit
f58c709945
208 changed files with 19280 additions and 2914 deletions
200
app/Http/Controllers/User/IncentiveController.php
Normal file
200
app/Http/Controllers/User/IncentiveController.php
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
use App\Http\Controllers\Admin\IncentiveController as AdminIncentiveController;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Incentive;
|
||||
use App\Models\IncentiveParticipant;
|
||||
use App\Models\UserAbo;
|
||||
use App\Services\Incentive\IncentivePointsLogRepairService;
|
||||
use App\Services\Incentive\IncentiveTracker;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Request;
|
||||
|
||||
class IncentiveController extends Controller
|
||||
{
|
||||
/**
|
||||
* Anzahl Plaetze in der User-Live-Rangliste (Gewinner-Highlight bleibt ueber max_winners, typ. Top 20).
|
||||
*/
|
||||
public const USER_RANKING_DISPLAY_LIMIT = 30;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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()
|
||||
->limit(self::USER_RANKING_DISPLAY_LIMIT)
|
||||
->get();
|
||||
|
||||
$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,
|
||||
'rankingDisplayLimit' => self::USER_RANKING_DISPLAY_LIMIT,
|
||||
'participateHasTrackableAbos' => $participateHasTrackableAbos,
|
||||
]);
|
||||
}
|
||||
|
||||
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<string>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue