301 lines
11 KiB
PHP
301 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Fo;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Fo\ParticipateRequest;
|
|
use App\Mail\NotifAdmin;
|
|
use App\Mail\NotifWinAdmin;
|
|
use App\Mail\PrizeWon;
|
|
use App\Mail\ReductionWon;
|
|
use App\Models\BannedIp;
|
|
use App\Models\Customer;
|
|
use App\Models\InstantWin;
|
|
use App\Models\Participation;
|
|
use App\Models\Reduction;
|
|
use LDCWeb\MesBR;
|
|
use App\Models\Settings;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
|
|
|
class EnterCodeController extends Controller
|
|
{
|
|
/**
|
|
* Show enter code form
|
|
*
|
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
|
*/
|
|
public function index()
|
|
{
|
|
/** @var \App\Models\Customer|null $customer */
|
|
$customer = auth('customer')->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');
|
|
}
|
|
}
|