user(); // * Only auth customer can access if (!auth('customer')->check()) { return redirect()->route('home'); } $nbParticipations = Participation::whereHas('customer', function ($q) use ($customer) { $q->whereId($customer->id); })->count(); $settings = app(Settings::class)->select('use_ean_codes', 'nb_participation_player')->first(); if ($nbParticipations >= $settings->nb_participation_player) { return view('front.basic.participation-exhausted', compact('settings')); } return view('front.basic.enter-code', compact('settings')); } /** * Participate Method * * @param ParticipateRequest $request * @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory */ public function participate(ParticipateRequest $request) { try { return DB::transaction(function () use ($request) { // Récupération des données à utilisées. /** @var \App\Models\Settings $settings */ $settings = app(Settings::class); /** @var \App\Models\Customer $customer */ $customer = auth('customer')->user(); /** @var \LDC\LDCCRM\Models\Customer $crmCustomer */ $crmCustomer = $customer->apiData; // * Cas IP bannie. if (BannedIp::where('ip', app('clientIp'))->exists()) { return view('front.basic.participation-exhausted', compact('settings')); } // * Cas nombre de participation maximale atteint. $nbParticipations = Participation::whereHas('customer', function ($q) use ($customer) { $q->whereId($customer->id); })->count(); if ($nbParticipations >= $settings->nb_participation_player) { return view('front.basic.participation-exhausted', compact('settings')); } // * Tous les cas "bloquants" sont passé, l'utilisateur participe à partir d'ici. $participation = new Participation(); $participation->code_unique_id = $request->code->id; $participation->code_ean_id = $request->code_ean ? $request->code_ean->id : null; $participation->ip = app('clientIp'); $participation->customer()->associate($customer); $participation->saveOrFail(); // * Gestion des instants gagnants. $userAlreadyWon = Participation::has('instantWin') ->whereHas('customer', function ($q) use ($customer) { $q->whereId($customer->id); })->first(); // * Si l'utilisateur actuel à déjà gagné un gros lot, pas d'instant gagnant. if ($userAlreadyWon) { return $this->serveCouponWin($settings, $participation, $crmCustomer); } /** @var \App\Models\InstantWin|null */ $instantWin = InstantWin::where('appear_date', '<', now()) ->whereDoesntHave('participation')->orderBy('appear_date', 'ASC') ->lockForUpdate()->first(); if ($instantWin) { // Ici si fail car unique dupliqué catch. try { // Gain d'un gros lot. return $this->instantWin( $settings, $participation, $crmCustomer, $instantWin ); } catch (\ErrorException $e) { report($e); // Unbind instant gagnant. $participation->instantWin()->deleteOrFail(); } //end try } return $this->serveCouponWin( $settings, $participation, $crmCustomer ); }); } catch (\ErrorException $e) { report($e); return back() ->withErrors('Une erreur est survenue, merci de réessayez ultérieurement.'); }//end try } /** * Handle instant wins * * @param Settings $settings * @param Participation $participation * @param CrmCustomer $crmCustomer * @param InstantWin $instantWin * @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory */ private function instantWin( Settings $settings, Participation &$participation, CrmCustomer $crmCustomer, InstantWin $instantWin ) { $participation->instantWin()->save($instantWin); Mail::to($crmCustomer->email)->send(new PrizeWon($crmCustomer, $instantWin->prize, $settings)); $mails = collect($settings->notification_emails); // ? Is settings.notification_emails empty ? if (!$mails->count()) { // ! Send to null (will send to MAIL_ADMIN and print warning in mail object) $mails = [null]; } foreach ($mails as $mail) { Mail::to($mail)->send(new NotifWinAdmin( $crmCustomer, $settings, $participation )); } return view("front.basic." . $instantWin->prize->gain_view->file_name, compact('settings')) ->with('prize', $instantWin->prize); } /** * Détermine si un BR doit être servi * renvoi la vue de gain BR ou la vue "Perdu" * * @param Settings $settings * @param Participation $participation * @param CrmCustomer $crmCustomer * @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory * @throws \ErrorException If no web coupons are available. */ private function serveCouponWin(Settings $settings, Participation $participation, CrmCustomer $crmCustomer) { // Si le jeu est 100% gagnant. if ($settings->reductions_activated) { if (!($coupon = $this->getRandomCoupon($settings))) { throw new \ErrorException('No web coupons are available'); } $reduction = $this->updateCoupon( $settings, $coupon['web_coupon_identifiant'], $participation, $crmCustomer ); if (!$reduction) { $participation->deleteOrFail(); abort(back()->withErrors('Une erreur est survenue, merci de réessayez ultérieurement.')); } Mail::to($crmCustomer->email) ->send(new ReductionWon($crmCustomer, $coupon['face_value'], $settings, $reduction)); return view('front.basic.reduction', compact('crmCoupon', 'coupon')); } else { return view('front.basic.loose'); } } /** * Get a random coupon * * @param Settings $settings * @return array|null */ private function getRandomCoupon(Settings $settings): ?array { $webCoupons = $settings->web_coupons; if (count($webCoupons) > 1) { $lots = []; foreach ($webCoupons as $webCoupon) { $lots[] = $webCoupon; } foreach ($lots as $lot) { for ($i = 0; $i < $lot->percentage; $i++) { $tmp[] = $lot; } } shuffle($tmp); return $tmp[0]; } else { return $webCoupons[0] ?? null; } } /** * Update a coupon * * FIXME: When mes BR will be updated. * * @param Settings $settings * @param integer $couponId * @param Participation $participation * @param CrmCustomer $crmCustomer * @return \App\Models\Reduction|null */ private function updateCoupon( Settings $settings, int $couponId, Participation $participation, CrmCustomer $crmCustomer ) { $reduction = null; $mesBR = new MesBR(config('mesbr.endpoint'), $settings->reductions_site, $settings->reductions_campaign); if ($crmUser->status === 'OK') { $mesBR->updateContact($crmUser->user); $result = $mesBR->updatePanier($crmUser->user, $couponId); if ($result["status"] === "OK") { $reduction = new Reduction(); $reduction->link = $result["link"]; $reduction->verification = $result["verif"]; $reduction->basket_id = $result["basketId"]; $reduction->saveOrFail(); $participation->reduction_id = $reduction->id; $participation->saveOrFail(); } else { Mail::to(config('mail.MAIL_ADMIN')) ->send(new NotifAdmin(\sprintf( 'MESBR : Une erreur est survenue. Code : %s Message : %s', $result["code"], $result["message"] ))); } } //end if return $reduction; } /** * Show Wining proof form * * @return \Illuminate\Http\Response */ public function formWinningProof() { /** @var \App\Models\Customer|null $customer */ $customer = auth('customer')->user(); // * Only auth customer can access if (!auth('customer')->check() or \get_class($customer) === Customer::class) { return redirect()->route('home'); } $participation = Participation::whereHas('customer', function ($q) use ($customer) { $q->whereId($customer->id); })->whereHas('instantWin')->where([ ['sticker', null], ['ticket', null], ['barcode', null] ])->first(); if ($participation) { return view('front.basic.winning-proof', compact('participation')); } return redirect()->route('home'); } }