Big freaking update TMP refactor Participate
This commit is contained in:
parent
1c4a7d915e
commit
1b388e7265
37 changed files with 549 additions and 389 deletions
|
|
@ -32,5 +32,5 @@ sur le job de generation des codes.
|
|||
## Améliorations possibles
|
||||
|
||||
- Empecher de supprimer des lots si le jeu est démarré ?
|
||||
- Permettre à une personne d'acceder à ses gains (formulaire si non complété, ou br si non télechargé)
|
||||
- Permettre à une personne d'acceder à ses gains (formulaire si non complété, ou br si non télechargé)
|
||||
en étant connecté via un lien sur le front (lien + formulaires)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class InstantWinController extends Controller
|
|||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$instantWinModelList = InstantWin::query()->orderBy('appear_date')->get();
|
||||
$instantWinModelList = InstantWin::query()->orderBy('available_at')->get();
|
||||
|
||||
return view('back::pages.instant-win.index', [
|
||||
'instantWinModelList' => $instantWinModelList
|
||||
|
|
@ -97,8 +97,8 @@ class InstantWinController extends Controller
|
|||
// * Save Instant wins
|
||||
$this->generateArray($lotsGlobal, $datesGlobal, 0)->each(function (WinDayCalendar $winDayCalendar) {
|
||||
$winDayCalendar->lots->each(function (WinTimeElement $winTimeElement) {
|
||||
$instantWin = new InstantWin();
|
||||
$instantWin->appear_date = $winTimeElement->time;
|
||||
$instantWin = new InstantWin();
|
||||
$instantWin->available_at = $winTimeElement->time;
|
||||
$instantWin->prize()->associate($winTimeElement->prize);
|
||||
$instantWin->saveOrFail();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use App\Mail\Won\DiscountWonMail;
|
|||
use App\Mail\Won\PrizeWonMail;
|
||||
use App\Models\Prize;
|
||||
use App\Models\Settings;
|
||||
use App\Models\Reduction;
|
||||
use App\Models\Discount;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
|
@ -79,11 +79,11 @@ class Re7Controller extends Controller
|
|||
$this->getRandomWeightedElementIndex($settings->web_coupons)
|
||||
);
|
||||
|
||||
if (!$settings->reductions_activated) {
|
||||
if (!$settings->discounts_activated) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
$crmCoupon = new Reduction();
|
||||
$crmCoupon = new Discount();
|
||||
return view('theme::pages.participation.won', compact('discount', 'crmCoupon'));
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ class Re7Controller extends Controller
|
|||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->reductions_activated) {
|
||||
if (!$settings->discounts_activated) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
|
|
@ -181,30 +181,4 @@ class Re7Controller extends Controller
|
|||
return response('', 404);
|
||||
} //end switch
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function for getting random values with weighting.
|
||||
* Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50)
|
||||
* An array like this means that "A" has a 5% chance of being selected, "B" 45%, and "C" 50%.
|
||||
* The return value is the array key, A, B, or C in this case. Note that the values assigned
|
||||
* do not have to be percentages. The values are simply relative to each other. If one value
|
||||
* weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66%
|
||||
* chance of being selected. Also note that weights should be integers.
|
||||
*
|
||||
* @param array<\App\Lib\Discount> $weightedValues
|
||||
* @return integer The winning key
|
||||
* @url https://stackoverflow.com/a/11872928/4355295
|
||||
*/
|
||||
private function getRandomWeightedElementIndex(array $weightedValues): int
|
||||
{
|
||||
mt_srand(time());
|
||||
$rand = mt_rand(1, max((int)collect($weightedValues)->sum('percentage'), 1));
|
||||
|
||||
foreach ($weightedValues as $key => $value) {
|
||||
$rand -= $value->percentage;
|
||||
if ($rand <= 0) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,33 @@ class Controller extends BaseController
|
|||
use AuthorizesRequests;
|
||||
use ValidatesRequests;
|
||||
|
||||
|
||||
/**
|
||||
* Utility function for getting random values with weighting.
|
||||
* Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50)
|
||||
* An array like this means that "A" has a 5% chance of being selected, "B" 45%, and "C" 50%.
|
||||
* The return value is the array key, A, B, or C in this case. Note that the values assigned
|
||||
* do not have to be percentages. The values are simply relative to each other. If one value
|
||||
* weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66%
|
||||
* chance of being selected. Also note that weights should be integers.
|
||||
*
|
||||
* @param array<\App\Lib\Discount> $weightedValues
|
||||
* @return integer The winning key
|
||||
* @url https://stackoverflow.com/a/11872928/4355295
|
||||
*/
|
||||
protected function getRandomWeightedElementIndex(array $weightedValues): int
|
||||
{
|
||||
mt_srand(time());
|
||||
$rand = mt_rand(1, max((int)collect($weightedValues)->sum('percentage'), 1));
|
||||
|
||||
foreach ($weightedValues as $key => $value) {
|
||||
$rand -= $value->percentage;
|
||||
if ($rand <= 0) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the redirection path for FO Auth controllers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -10,117 +10,133 @@ use App\Mail\NotifWinAdmin;
|
|||
use App\Mail\PrizeWon;
|
||||
use App\Mail\DiscountWonMail;
|
||||
use App\Models\BannedIp;
|
||||
use App\Models\Customer;
|
||||
use App\Models\InstantWin;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Reduction;
|
||||
use App\Models\Discount;
|
||||
use LDCWeb\MesBR;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
|
||||
class ParticipateController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display participation form
|
||||
*
|
||||
* @var \LDCCRM\ApiV1
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
private $apiCrm;
|
||||
|
||||
/**
|
||||
* EnterCodeController
|
||||
*/
|
||||
public function __construct()
|
||||
public function participate(): View
|
||||
{
|
||||
// $this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show enter code form
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function participate()
|
||||
{
|
||||
// $nbParticipations = Participation::where('user_id', Auth::user()->id)->count();
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
// if ($nbParticipations >= $settings->nb_participation_player) {
|
||||
// return view('theme::participation-exhausted', compact('settings'));
|
||||
// }
|
||||
return view('theme::enter-code', compact('settings'));
|
||||
if (Gate::check('participate', Participation::class)) {
|
||||
return view('theme::pages.participation-exhausted');
|
||||
}
|
||||
return view('theme::pages.enter-code');
|
||||
}
|
||||
|
||||
/**
|
||||
* Participate Method
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\ParticipateRequest $request
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participateSubmit(ParticipateRequest $request)
|
||||
public function participateSubmit(ParticipateRequest $request): View
|
||||
{
|
||||
// Récupération des données à utilisées.
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
// * Cas IP bannie.
|
||||
if (BannedIp::query()->where('ip', app('clientIp'))->exists()) {
|
||||
return view('theme::participation-exhausted', compact('settings'));
|
||||
if (Gate::check('participate', Participation::class)) {
|
||||
return view('theme::pages.participation-exhausted');
|
||||
}
|
||||
|
||||
// * Cas nombre de participation maximale atteint.
|
||||
$nbParticipations = Participation::where('user_id', auth('backend')->user()->id)->count();
|
||||
if ($nbParticipations >= $settings->nb_participation_player) {
|
||||
return view('theme::participation-exhausted', compact('settings'));
|
||||
}
|
||||
return DB::transaction(function () use ($request) {
|
||||
// ! On verrouille le ou les instants gagnant
|
||||
/** @var \App\Models\InstantWin|null */
|
||||
$instantWin = InstantWin::query()->lockForUpdate()
|
||||
->where('available_at', '<', now())
|
||||
->where('won', false)
|
||||
->get()->sortBy('available_at', 'ASC')->first();
|
||||
|
||||
// * Tous les cas "bloquants" sont passé, l'utilisateur participe à partir d'ici.
|
||||
$participation = new Participation();
|
||||
$participation->user_id = auth('backend')->user()->id;
|
||||
$participation->code_unique_id = $request->code->id;
|
||||
$participation->code_ean_id = $request->code_ean ? $request->code_ean->id : null;
|
||||
$participation->ip = app('clientIp');
|
||||
$participation->save();
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
// * Gestion des instants gagnants.
|
||||
$userAlreadyWon = Participation::has('instantWin')
|
||||
->whereHas('user', function ($q) {
|
||||
$q->whereId(auth('backend')->user()->id);
|
||||
})->first();
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
// * Si l'utilisateur actuel à déjà gagné un gros lot, pas d'instant gagnant.
|
||||
if ($userAlreadyWon) {
|
||||
return $this->serveCouponWin($settings, $participation);
|
||||
}
|
||||
/** @var \App\Models\Code */
|
||||
$code = $request->post('code');
|
||||
/** @var \App\Models\Product|null */
|
||||
$product = $request->post('code');
|
||||
|
||||
$instantWin = InstantWin::where([['appear_date', '<', now()], ['won', 0]])
|
||||
->orderBy('appear_date', 'ASC')->first();
|
||||
if ($instantWin) {
|
||||
// * Make new participation
|
||||
$participation = Participation::makeNew(
|
||||
app('clientIp'),
|
||||
$customer,
|
||||
$code,
|
||||
$product
|
||||
);
|
||||
|
||||
// * Si l'utilisateur actuel à déjà gagné un gros lot, pas d'instant gagnant.
|
||||
if (Participation::customerAlreadyHasAnInstantWin($customer) or !$instantWin) {
|
||||
// ? Les BR sont activés ?
|
||||
if (!$settings->discounts_activated) {
|
||||
// * On enregistre la participation du joueur.
|
||||
$participation->save();
|
||||
|
||||
// * Pas de coupons disponibles, le joueur à perdu
|
||||
return view('theme::pages.participation.loose');
|
||||
}
|
||||
|
||||
// * Le joueur à gagné un coupon.
|
||||
$responseView = $this->serveCouponWin($settings, $participation);
|
||||
|
||||
// * On enregistre la participation du joueur.
|
||||
$participation->save();
|
||||
|
||||
return $responseView;
|
||||
}
|
||||
|
||||
// * Le joueur à remporté un instant gagnant
|
||||
// Ici si fail car unique dupliqué catch.
|
||||
try {
|
||||
// Gain d'un gros lot.
|
||||
return $this->instantWin($settings, $request, $participation, $instantWin);
|
||||
$this->instantWin($request, $participation, $instantWin);
|
||||
return view(
|
||||
'theme::pages.participation.won_prize',
|
||||
compact('settings')
|
||||
)->with('prize', $instantWin->prize);
|
||||
} catch (\ErrorException $e) {
|
||||
// Unbind instant gagnant.
|
||||
$participation->instantWin()->delete();
|
||||
// phpcs:ignore
|
||||
// TODO: si erreur il faut envoyer un mail à equipe.web@ldc.fr.
|
||||
} //end try
|
||||
}
|
||||
return $this->serveCouponWin($settings, $participation);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle instant wins
|
||||
*
|
||||
* @param Settings $settings
|
||||
* @param Request $request
|
||||
* @param Participation $participation
|
||||
* @param InstantWin|null $instantWin
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @param string $serial
|
||||
* @param \App\Models\Participation $participation
|
||||
* @param \App\Models\InstantWin|null $instantWin
|
||||
* @return void
|
||||
*/
|
||||
private function instantWin(Settings $settings, Request $request, Participation &$participation, $instantWin)
|
||||
{
|
||||
private function instantWin(
|
||||
string $serial,
|
||||
Participation $participation,
|
||||
InstantWin|null $instantWin
|
||||
): void {
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
$instantWin->won = true;
|
||||
// Should save now to prevent next player win on the same winning moment.
|
||||
$instantWin->save();
|
||||
|
|
@ -179,96 +195,120 @@ class ParticipateController extends Controller
|
|||
Mail::to($mail->email)->send(new NotifWinAdmin($settings, $participation));
|
||||
}
|
||||
$participation->save();
|
||||
return view('theme::pages.participation.won_prize', 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
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @param \App\Models\Settings $settings The game settings.
|
||||
* @param \App\Models\Participation $participation The actual participation
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
private function serveCouponWin(Settings $settings, Participation $participation)
|
||||
private function serveCouponWin(Settings $settings, Participation $participation): View
|
||||
{
|
||||
// Si le jeu est 100% gagnant.
|
||||
if ($settings->reductions_activated === 1) {
|
||||
$coupon = $this->getRandomCoupon($settings);
|
||||
$crmCoupon = $this->updateCoupon($settings, $coupon->web_coupon_identifiant, $participation);
|
||||
if (!$crmCoupon) {
|
||||
$participation->delete();
|
||||
return back()->withErrors("Une erreur est survenue, merci de réessayez ultérieurement.");
|
||||
}
|
||||
Mail::to(Auth::user()->email)->send(new DiscountWonMail(Auth::user(), $coupon, $settings, $crmCoupon));
|
||||
return view('theme::reduction', compact('crmCoupon', 'coupon'));
|
||||
} else {
|
||||
return view('theme::loose');
|
||||
/** @var \App\Lib\Discount */
|
||||
$discount = Arr::get(
|
||||
$settings->web_coupons,
|
||||
$this->getRandomWeightedElementIndex($settings->web_coupons)
|
||||
);
|
||||
|
||||
// return response((new DiscountWonMail(
|
||||
// new Address(
|
||||
// $user->email,
|
||||
// $user->first_name
|
||||
// ),
|
||||
// $settings->name,
|
||||
// $discount,
|
||||
// config('app.url')
|
||||
// ))->render());
|
||||
|
||||
$crmCoupon = $this->setDiscountAsWon($discount);
|
||||
|
||||
// * On associe le coupon à la participation
|
||||
$participation->discount()->associate($discount);
|
||||
|
||||
|
||||
|
||||
|
||||
if (!$crmCoupon) {
|
||||
$participation->delete();
|
||||
return back()->withErrors("Une erreur est survenue, merci de réessayez ultérieurement.");
|
||||
}
|
||||
Mail::to(Auth::user()->email)->send(new DiscountWonMail(Auth::user(), $coupon, $settings, $crmCoupon));
|
||||
return view('theme::discount', compact('crmCoupon', 'coupon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random coupon
|
||||
* Try Call CRM + MesBr to setup disount
|
||||
*
|
||||
* @param Settings $settings
|
||||
* @return mixed
|
||||
* @param \App\Models\Customer $customer
|
||||
* @param \App\Models\Discount $discount
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \Illuminate\Database\Eloquent\InvalidCastException
|
||||
*/
|
||||
private function getRandomCoupon(Settings $settings)
|
||||
private function setDiscountAsWon(Customer $customer, Discount $discount): void
|
||||
{
|
||||
$webCoupons = json_decode($settings->web_coupons);
|
||||
if (count($webCoupons) > 1) {
|
||||
$lots = [];
|
||||
foreach ($webCoupons as $webCoupon) {
|
||||
$lots[] = $webCoupon;
|
||||
// * Phase - 1 Recupération des informations CRM
|
||||
/** @var \LDC\LDCCRM\Models\Customer|null */
|
||||
$crmUser = null;
|
||||
|
||||
try {
|
||||
$crmUser = $customer->api_data;
|
||||
|
||||
// ? Le compte du joueur est vérifié ?
|
||||
if (!$crmUser->status) {
|
||||
// * Le joueur doit avoir un compte vérifié pour participer.
|
||||
response()->redirectToRoute('fo.verification.notice')
|
||||
->with('error', trans('Pour participer votre compte doit être activé'))
|
||||
->throwResponse();
|
||||
}
|
||||
foreach ($lots as $lot) {
|
||||
for ($i = 0; $i < $lot->percentage; $i++) {
|
||||
$tmp[] = $lot;
|
||||
}
|
||||
} catch (ApiErrorException $e) {
|
||||
// * Customer is not found.
|
||||
if ($e->getApiError()->equals(ApiError::modelNotFound())) {
|
||||
// * Déconnexion immédiate et retour maison.
|
||||
auth('frontend')->logout();
|
||||
response()->redirectToRoute('fo.home')
|
||||
->with('error', trans('Une erreur est survenue, compte introuvable.'))
|
||||
->throwResponse();
|
||||
}
|
||||
shuffle($tmp);
|
||||
return $tmp[0];
|
||||
report($e);
|
||||
Log::error('Unhandled response ' . $e->getApiError()->label);
|
||||
// * Retenter ?
|
||||
back()->with('error', trans('Une erreur est survenue, veuillez réssayer.'))->throwResponse();
|
||||
} catch (CrmException | \Exception $e) {
|
||||
report($e);
|
||||
// * Retenter ?
|
||||
back()->with('error', trans('Une erreur est survenue, veuillez réssayer.'))->throwResponse();
|
||||
} //end try
|
||||
|
||||
// * Phase - 2 Mise à jour du coupon dans MesBr
|
||||
/** @var \LDCWEB\MesBR */
|
||||
$mesBR = app('mesBrAPI');
|
||||
|
||||
$mesBR->updateCustomer($crmUser->user);
|
||||
$result = $mesBR->updatePanier($crmUser->user, $discount);
|
||||
if ($result["status"] === "OK") {
|
||||
$discount = new Discount();
|
||||
$discount->link = $result["link"];
|
||||
$discount->verification = $result["verif"];
|
||||
$discount->basket_id = $result["basketId"];
|
||||
$discount->save();
|
||||
} else {
|
||||
return $webCoupons[0];
|
||||
Mail::to(config('mail.admin'))
|
||||
->send(new NotifAdmin(\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
$result["code"],
|
||||
$result["message"]
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a coupon
|
||||
*
|
||||
* @param Settings $settings
|
||||
* @param mixed $coupon
|
||||
* @param Participation $participation
|
||||
* @return \App\Models\Reduction|null
|
||||
*/
|
||||
private function updateCoupon(Settings $settings, mixed $coupon, Participation $participation)
|
||||
{
|
||||
$reduction = null;
|
||||
$mesBR = new MesBR(config('mesbr.endpoint'), $settings->reductions_site, $settings->reductions_campaign);
|
||||
|
||||
$crmUser = $this->apiCrm->getCustomer(Auth::user()->crm_id);
|
||||
if ($crmUser->status === 'OK') {
|
||||
$mesBR->updateContact($crmUser->user);
|
||||
$result = $mesBR->updatePanier($crmUser->user, $coupon);
|
||||
if ($result["status"] === "OK") {
|
||||
$reduction = new Reduction();
|
||||
$reduction->link = $result["link"];
|
||||
$reduction->verification = $result["verif"];
|
||||
$reduction->basket_id = $result["basketId"];
|
||||
$reduction->save();
|
||||
$participation->reduction_id = $reduction->id;
|
||||
$participation->save();
|
||||
} else {
|
||||
Mail::to(config('mail.admin'))
|
||||
->send(new NotifAdmin(\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
$result["code"],
|
||||
$result["message"]
|
||||
)));
|
||||
}
|
||||
} //end if
|
||||
return $reduction;
|
||||
// return $discount;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33,16 +33,16 @@ class UpdateSettingsRequest extends FormRequest
|
|||
'use_ean_codes' => $this->boolean('use_ean_codes'),
|
||||
'activated_teaser' => $this->boolean('activated_teaser'),
|
||||
'activated_close_page' => $this->boolean('activated_close_page'),
|
||||
'reductions_activated' => $this->boolean('reductions_activated'),
|
||||
'discounts_activated' => $this->boolean('discounts_activated'),
|
||||
'winning_proof' => $this->boolean('winning_proof'),
|
||||
// Arrays.
|
||||
'notification_emails' => collect($this->input('notification_emails'))->filter()->all(),
|
||||
// Remove some dates if the checkbox is uncheck.
|
||||
'close_page_active_date' => $this->input('activated_close_page') ?
|
||||
$this->input('close_page_active_date') : null,
|
||||
// Remove reductions datas if the reduction checkbox is uncheck.
|
||||
'reductions_site' => $this->input('reductions_activated') ? $this->input('reductions_site') : null,
|
||||
'reductions_campaign' => $this->input('reductions_activated') ? $this->input('reductions_campaign') : null,
|
||||
// Remove discounts datas if the discount checkbox is uncheck.
|
||||
'discounts_site' => $this->input('discounts_activated') ? $this->input('discounts_site') : null,
|
||||
'discounts_campaign' => $this->input('discounts_activated') ? $this->input('discounts_campaign') : null,
|
||||
'web_coupons' => collect($this->input('web_coupons'))->filter()->all(),
|
||||
]);
|
||||
}
|
||||
|
|
@ -69,13 +69,13 @@ class UpdateSettingsRequest extends FormRequest
|
|||
'close_page_active_date' => 'nullable|required_if:activated_close_page,true,1|date|after_or_equal:today',
|
||||
'redirect_close' => 'required|url:http,https',
|
||||
|
||||
'reductions_activated' => 'required|boolean',
|
||||
'reductions_site' => 'nullable|required_if:reductions_activated,true,1|string|min:3|max:255',
|
||||
'reductions_campaign' => 'nullable|required_if:reductions_activated,true,1|string|min:3|max:255',
|
||||
'discounts_activated' => 'required|boolean',
|
||||
'discounts_site' => 'nullable|required_if:discounts_activated,true,1|string|min:3|max:255',
|
||||
'discounts_campaign' => 'nullable|required_if:discounts_activated,true,1|string|min:3|max:255',
|
||||
|
||||
'web_coupons' => [
|
||||
'present', 'array', function ($attribute, $value, $fail) {
|
||||
if ($this->post('reductions_activated') and !collect($value)->filter()->count()) {
|
||||
if ($this->post('discounts_activated') and !collect($value)->filter()->count()) {
|
||||
$fail(trans('validation.min.array', [
|
||||
'attribute' => Arr::get($this->attributes(), $attribute),
|
||||
'min' => 1
|
||||
|
|
@ -138,9 +138,9 @@ class UpdateSettingsRequest extends FormRequest
|
|||
'close_page_active_date' => trans('validation.custom.close_page_active_date'),
|
||||
'redirect_close' => trans('validation.custom.redirect_close'),
|
||||
'winning_proof' => trans('validation.custom.winning_proof'),
|
||||
'reductions_activated' => trans('validation.custom.reductions_activated'),
|
||||
'reductions_site' => trans('validation.custom.reductions_site'),
|
||||
'reductions_campaign' => trans('validation.custom.reductions_campaign'),
|
||||
'discounts_activated' => trans('validation.custom.discounts_activated'),
|
||||
'discounts_site' => trans('validation.custom.discounts_site'),
|
||||
'discounts_campaign' => trans('validation.custom.discounts_campaign'),
|
||||
|
||||
'web_coupons' => trans('Tableau des coupons'),
|
||||
'web_coupons.*.web_coupon_identifiant' => trans('Identifiant coupon :index'),
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ use App\Models\Code;
|
|||
use App\Models\Participation;
|
||||
use App\Models\Product;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\Serial\Exceptions\SerialCasterException;
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ class ParticipateRequest extends FormRequest
|
|||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('frontend')->check();
|
||||
return Gate::check('participate', Participation::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -30,50 +31,21 @@ class ParticipateRequest extends FormRequest
|
|||
*/
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
/**
|
||||
* * Check si les codes ean sont utilisés, auquel cas
|
||||
* * on test celui envoyé pour savoir s'il est correct.
|
||||
* Modif demande vincent :
|
||||
* Tester code ean existe avec 13, puis 8 puis 7 chars
|
||||
* Si le code EAN est trouvé dans la liste, alors on prend l'objet correspondant,
|
||||
* sinon on prend le premier objet qui contient les 7 1er chiffres (cas des EAN pds)
|
||||
*
|
||||
* Dans la base chaque code ean doit être rentré dans sa valeur absolue
|
||||
* càd que les code ean 8 sont de longueur 8, 7 de longueur7 et 13 de longueur 13.
|
||||
*/
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
if ($settings->use_ean_codes) {
|
||||
// ! We need to validate ean is 13 before resolving ean code.
|
||||
/** @throws \Illuminate\Validation\ValidationException */
|
||||
Validator::validate($this->all(), [
|
||||
'code_ean' => 'required|digits:13'
|
||||
], $this->attributes());
|
||||
|
||||
// * Union pour faire des recherches séparée en une seule requête.
|
||||
/** @var \App\Models\Product|null */
|
||||
$codeEan = Product::where('code_ean', $this->code_ean)
|
||||
->union(Product::where('code_ean', Str::limit($this->code_ean, 8, '')))
|
||||
->union(Product::where('code_ean', Str::limit($this->code_ean, 7, '')))
|
||||
->first() ?? false;
|
||||
|
||||
$this->merge(['code_ean' => $codeEan]);
|
||||
} //end if
|
||||
try {
|
||||
$this->merge([
|
||||
'serial' => $this->code,
|
||||
'code' => Code::whereId(Code::serialToInt(Str::upper(\strval($this->code))))->first() ?? false,
|
||||
'code' => Code::query()->where('id', Code::serialToInt(
|
||||
Str::upper(\strval($this->code))
|
||||
))->first() ?? false,
|
||||
]);
|
||||
} catch (SerialCasterException $e) {
|
||||
} catch (SerialCasterException) {
|
||||
// * Provoquer l'affichage code incorrect.
|
||||
$this->merge([
|
||||
'code' => false,
|
||||
]);
|
||||
} finally {
|
||||
$this->merge([
|
||||
'accept_rules' => $this->accept_rules ? true : false
|
||||
'code_ean' => (string)$this->string('code_ean')->padLeft(13, '0'),
|
||||
'accept_rules' => $this->boolean('accept_rules')
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -90,61 +62,80 @@ class ParticipateRequest extends FormRequest
|
|||
|
||||
$rules = [
|
||||
'accept_rules' => 'required|boolean|accepted',
|
||||
'code' => [
|
||||
'serial' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) use ($settings) {
|
||||
if (
|
||||
$value === false or
|
||||
!\is_object($value) or
|
||||
\get_class($value) !== Code::class
|
||||
) {
|
||||
$fail('Code unique incorrect, veuillez réessayer.');
|
||||
return false;
|
||||
} elseif ($value->code_used === 1) {
|
||||
$fail('Ce code unique n\'est plus utilisable.');
|
||||
return false;
|
||||
// ? Le Code unique est resolved ?
|
||||
if ($value === false or !\is_object($value) or \get_class($value) !== Code::class) {
|
||||
$fail(trans('Code unique incorrect, veuillez réessayer.'));
|
||||
return;
|
||||
}
|
||||
/** @var \App\Models\Code $value */
|
||||
// ? Code unique déjà trop utilisé ?
|
||||
if ($value->code_used) {
|
||||
$fail(trans('Ce code unique n\'est plus utilisable.'));
|
||||
return;
|
||||
}
|
||||
|
||||
/** Request réutilisable */
|
||||
$participationQuery = Participation::query()
|
||||
->whereHas('code', fn (Builder $q) => $q->where('id', $value->id));
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
// * Check si l'utilisateur n'a pas déjà utilisé ce code.
|
||||
$query = Participation::where([
|
||||
['code_unique_id', $this->code->id],
|
||||
['user_id', auth('backend')->user()->id]
|
||||
]);
|
||||
$query = (clone $participationQuery)->whereHas(
|
||||
'customer',
|
||||
fn (Builder $q) => $q->where('id', $customer->id)
|
||||
);
|
||||
// ! Une seule participation avec un code donné par joueur
|
||||
if ($query->exists()) {
|
||||
$fail('Vous avez déjà utilisé ce code unique.');
|
||||
$fail(trans('Vous avez déjà utilisé ce code unique.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$codeNbUsage = Participation::where('code_unique_id', $this->code->id)
|
||||
->count();
|
||||
|
||||
// * Gestion du nombre d'utilisation d'un code.
|
||||
if ($codeNbUsage >= $settings->nb_unique_code_use) {
|
||||
$this->code->code_used = 1;
|
||||
return back()->withErrors("Ce code unique n'est plus utilisable.");
|
||||
} else {
|
||||
if ($codeNbUsage + 1 >= $settings->nb_unique_code_use) {
|
||||
$this->code->code_used = 1;
|
||||
}
|
||||
// ? Le code unique à été trop utilisé ?
|
||||
if ((clone $participationQuery)->count() >= $settings->nb_unique_code_use) {
|
||||
$value->code_used = true;
|
||||
$value->saveOrFail();
|
||||
$fail(trans('Ce code unique n\'est plus utilisable.'));
|
||||
return;
|
||||
}
|
||||
$this->code->saveOrFail();
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* * Check si les codes ean sont utilisés, auquel cas
|
||||
* * on test celui envoyé pour savoir s'il est correct.
|
||||
* Modif demande vincent :
|
||||
* Tester code ean existe avec 13, puis 8 puis 7 chars
|
||||
* Si le code EAN est trouvé dans la liste, alors on prend l'objet correspondant,
|
||||
* sinon on prend le premier objet qui contient les 7 1er chiffres (cas des EAN pds)
|
||||
*
|
||||
* Dans la base chaque code ean doit être rentré dans sa valeur absolue
|
||||
* càd que les code ean 8 sont de longueur 8, 7 de longueur7 et 13 de longueur 13.
|
||||
*/
|
||||
// ? Does the game use EAN Codes ?
|
||||
if ($settings->use_ean_codes) {
|
||||
$rules = \array_merge($rules, [
|
||||
'code_ean' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if (!\is_object($value) or \get_class($value) !== Product::class) {
|
||||
$fail('Le code barre entré est incorrect, veuillez réessayer.');
|
||||
}
|
||||
}
|
||||
]
|
||||
$rules = \array_merge($rules, ['code_ean' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
// * Union pour faire des recherches séparée en une seule requête.
|
||||
// ! code_ean is already str_padded to 13
|
||||
$productQuery = Product::query()->where('code_ean', $this->post('code_ean'))
|
||||
->union(Product::where('code_ean', Str::limit($this->post('code_ean'), 8, '')))
|
||||
->union(Product::where('code_ean', Str::limit($this->post('code_ean'), 7, '')));
|
||||
|
||||
]);
|
||||
if (!$productQuery->exists()) {
|
||||
$fail(trans('Le code barre entré est incorrect, veuillez réessayer.'));
|
||||
}
|
||||
}
|
||||
]]);
|
||||
}
|
||||
return $rules;
|
||||
}
|
||||
|
|
@ -158,8 +149,8 @@ class ParticipateRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'code_ean' => \trans('code barre'),
|
||||
'serial' => \trans('code unique'),
|
||||
'accept_rules' => \trans('règlements du jeu'),
|
||||
'code' => \trans('code unique'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Models;
|
||||
|
||||
use App\Casts\Ip;
|
||||
use App\Traits\Models\IsCachedAsCollection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
|
|
@ -13,6 +14,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||
*/
|
||||
class BannedIp extends Model
|
||||
{
|
||||
use IsCachedAsCollection;
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
|
|
@ -37,4 +39,18 @@ class BannedIp extends Model
|
|||
protected $casts = [
|
||||
'ip' => Ip::class
|
||||
];
|
||||
|
||||
// * EVENTS
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(fn () => self::removeCached());
|
||||
static::updated(fn () => self::removeCached());
|
||||
static::deleted(fn () => self::removeCached());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ use Kwaadpepper\Serial\SerialCaster;
|
|||
/**
|
||||
* Code.
|
||||
*
|
||||
* @property boolean $code_used Is the code used ?
|
||||
* @property boolean $code_used Is the code used too much ?
|
||||
* @property boolean $code_exported Is the code exported ?
|
||||
* @property \Illuminate\Support\Carbon $date_creation Date of creation.
|
||||
* @property \Illuminate\Support\Carbon $date_creation Code creation date.
|
||||
*
|
||||
* @property-read string|null $code_unique The unique code
|
||||
*
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace App\Models;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Reduction.
|
||||
* Bon de réduction
|
||||
*
|
||||
* @property string $link Link
|
||||
* @property string $basket_id Basket id
|
||||
|
|
@ -15,7 +15,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||
*
|
||||
* @property-read \App\Models\Participation $participation Associated participation.
|
||||
*/
|
||||
class Reduction extends Model
|
||||
class Discount extends Model
|
||||
{
|
||||
// * RELATIONSHIPS
|
||||
|
||||
|
|
@ -7,8 +7,8 @@ use Illuminate\Database\Eloquent\Model;
|
|||
/**
|
||||
* InstantWin.
|
||||
*
|
||||
* @property \Illuminate\Support\Carbon $appear_date Appear date
|
||||
* @property boolean $won Is the prize won ?
|
||||
* @property \Illuminate\Support\Carbon $available_at When the instant win will be available.
|
||||
* @property boolean $won Is the prize won ?
|
||||
*
|
||||
* @property-read \App\Models\Prize $prize Associated prize.
|
||||
* @property-read \App\Models\Participation $participation Associated participation.
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use IPLib\Address\AddressInterface;
|
||||
|
||||
/**
|
||||
* Participation.
|
||||
|
|
@ -21,7 +23,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @property-read \App\Models\Code $code Associated code.
|
||||
* @property-read \App\Models\Product $product Associated product.
|
||||
* @property-read \App\Models\InstantWin $instantWin Associated instantWin.
|
||||
* @property-read \App\Models\Reduction $reduction Associated reduction.
|
||||
* @property-read \App\Models\Discount $discount Associated discount.
|
||||
*/
|
||||
class Participation extends Model
|
||||
{
|
||||
|
|
@ -68,13 +70,13 @@ class Participation extends Model
|
|||
}
|
||||
|
||||
/**
|
||||
* One to one Reduction relation
|
||||
* One to one Discount relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
*/
|
||||
public function reduction()
|
||||
public function discount()
|
||||
{
|
||||
return $this->hasOne(Reduction::class);
|
||||
return $this->hasOne(Discount::class);
|
||||
}
|
||||
|
||||
// * GETTERS
|
||||
|
|
@ -90,4 +92,44 @@ class Participation extends Model
|
|||
get: fn () => optional($this->product)->code_ean,
|
||||
);
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Make new participation but do not persist on DB
|
||||
*
|
||||
* @param \IPLib\Address\AddressInterface $ip Ip for the participation.
|
||||
* @param \App\Models\Customer $customer The Customer playing the game.
|
||||
* @param \App\Models\Code $code The unique code used to play.
|
||||
* @param null|\App\Models\Product $product The product that holds the sticker if codes are actived.
|
||||
* @return \App\Models\Participation
|
||||
*/
|
||||
public static function makeNew(
|
||||
AddressInterface $ip,
|
||||
Customer $customer,
|
||||
Code $code,
|
||||
Product|null $product = null
|
||||
): self {
|
||||
$self = new self();
|
||||
$self->ip = $ip;
|
||||
$self->customer()->associate($customer);
|
||||
$self->code()->associate($code);
|
||||
if ($product) {
|
||||
$self->product()->associate($product);
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a customer has already won
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @return boolean
|
||||
*/
|
||||
public static function customerAlreadyHasAnInstantWin(Customer $customer): bool
|
||||
{
|
||||
return self::query()->whereHas('instantWin')
|
||||
->whereHas('user', fn (Builder $q) => $q->where('id', $customer->id))
|
||||
->exists();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @property boolean $activated_close_page Is the close page active ?
|
||||
* @property \Illuminate\Support\Carbon $close_page_active_date End date of the close page
|
||||
* @property string $redirect_close Link to redirect when the game is ended
|
||||
* @property boolean $reductions_activated Are the reductions active ?
|
||||
* @property string $reductions_site Reduction site
|
||||
* @property string $reductions_campaign Reduction campaign
|
||||
* @property boolean $discounts_activated Are the discounts active ?
|
||||
* @property string $discounts_site Discount MesBr site
|
||||
* @property string $discounts_campaign Discount MesBr campaign
|
||||
* @property array<\App\Lib\Discount> $web_coupons Array of web coupons
|
||||
* @property array<string> $notification_emails Array of email to notify when there's a winnner
|
||||
* @property boolean $winning_proof Is the winning proof needed
|
||||
|
|
@ -54,9 +54,9 @@ class Settings extends Model
|
|||
'activated_close_page',
|
||||
'close_page_active_date',
|
||||
'redirect_close',
|
||||
'reductions_activated',
|
||||
'reductions_site',
|
||||
'reductions_campaign',
|
||||
'discounts_activated',
|
||||
'discounts_site',
|
||||
'discounts_campaign',
|
||||
'web_coupons',
|
||||
'notification_emails',
|
||||
'winning_proof',
|
||||
|
|
|
|||
|
|
@ -3,8 +3,12 @@
|
|||
namespace App\Policies;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Models\BannedIp;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Participation;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
|
||||
class ParticipationPolicy
|
||||
{
|
||||
|
|
@ -18,4 +22,24 @@ class ParticipationPolicy
|
|||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::marketing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wether a customer can participate
|
||||
*
|
||||
* @param \App\Models\Customer $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function participate(Customer $authUser): bool
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
// * Deny banned IP, Check did not participate too much
|
||||
return !BannedIp::getCached()->where('ip', app('clientIp'))->exists() or
|
||||
Participation::query()->whereHas(
|
||||
'customer',
|
||||
fn (Builder $q) =>
|
||||
$q->where('id', $authUser->id)
|
||||
)->count() >= $settings->nb_participation_player;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ class AppServiceProvider extends ServiceProvider
|
|||
Carbon::setLocale(config('app.locale'));
|
||||
Pluralizer::useLanguage('french');
|
||||
|
||||
// * Settings Provider
|
||||
app()->singleton(Settings::class, function () {
|
||||
if (!($settings = Settings::getCached()->first())) {
|
||||
throw new \ErrorException('Settings not found in DB');
|
||||
|
|
|
|||
30
app/Providers/MesBrApiServiceProvider.php
Normal file
30
app/Providers/MesBrApiServiceProvider.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use LDCWEB\MesBR;
|
||||
|
||||
class MesBrApiServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
App::singleton('mesBrAPI', function () {
|
||||
/** @var \App\Models\Settings|null */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
return new MesBR(
|
||||
config('mesbr.endpoint'),
|
||||
$settings->discounts_site,
|
||||
$settings->discounts_campaign
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -197,6 +197,7 @@ return [
|
|||
App\Providers\TranslationServiceProvider::class,
|
||||
App\Providers\ViewServiceProvider::class,
|
||||
App\Providers\CrmApiServiceProvider::class,
|
||||
App\Providers\MesBrApiServiceProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateSettings extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -34,10 +34,10 @@ class CreateSettings extends Migration
|
|||
->comment('Date limite pour utiliser la page de cloture, sinon redirection vers close page');
|
||||
$table->string('redirect_close')->comment('Lien de redirection du jeu quand celui-ci est fermé');
|
||||
|
||||
$table->boolean('reductions_activated')
|
||||
$table->boolean('discounts_activated')
|
||||
->comment('Les bon de réduction sont activés (gains de BR possibles)');
|
||||
$table->string('reductions_site')->nullable()->comment('Champ mesBR "site"');
|
||||
$table->string('reductions_campaign')->nullable()->comment('Champ mesBR "campaign"');
|
||||
$table->string('discounts_site')->nullable()->comment('Champ mesBR "site"');
|
||||
$table->string('discounts_campaign')->nullable()->comment('Champ mesBR "campaign"');
|
||||
|
||||
$table->json('web_coupons')->nullable()->comment('Les coupons disponibles comme gain pour les joueurs');
|
||||
$table->json('notification_emails')->nullable()->comment('Les mails à notifier pour les évènements de jeu');
|
||||
|
|
@ -57,4 +57,4 @@ class CreateSettings extends Migration
|
|||
{
|
||||
Schema::dropIfExists('settings');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateCodes extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -15,9 +15,9 @@ class CreateCodes extends Migration
|
|||
{
|
||||
Schema::create('codes', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('id')->primary();
|
||||
$table->boolean('code_used')->default(0);
|
||||
$table->boolean('code_exported')->default(0);
|
||||
$table->date('date_creation');
|
||||
$table->boolean('code_used')->default(0)->comment('Is the code used too much ?');
|
||||
$table->boolean('code_exported')->default(0)->comment('Has the code been exported ?');
|
||||
$table->date('date_creation')->comment('Code creation date');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -30,4 +30,4 @@ class CreateCodes extends Migration
|
|||
{
|
||||
Schema::dropIfExists('codes');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBannedIps extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -29,4 +29,4 @@ class CreateBannedIps extends Migration
|
|||
{
|
||||
Schema::dropIfExists('banned_ips');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateFaqThemes extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -29,4 +29,4 @@ class CreateFaqThemes extends Migration
|
|||
{
|
||||
Schema::dropIfExists('faq_themes');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateFaqQuestions extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -31,4 +31,4 @@ class CreateFaqQuestions extends Migration
|
|||
{
|
||||
Schema::dropIfExists('faq_questions');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateReductions extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -13,7 +13,7 @@ class CreateReductions extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('reductions', function (Blueprint $table) {
|
||||
Schema::create('discounts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('link');
|
||||
$table->string('basket_id');
|
||||
|
|
@ -29,6 +29,6 @@ class CreateReductions extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('reductions');
|
||||
Schema::dropIfExists('discounts');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreatePrizes extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -40,4 +40,4 @@ class CreatePrizes extends Migration
|
|||
{
|
||||
Schema::dropIfExists('prizes');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateJobsTable extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -33,4 +33,4 @@ class CreateJobsTable extends Migration
|
|||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateModelRangesTable extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -28,4 +28,4 @@ class CreateModelRangesTable extends Migration
|
|||
{
|
||||
Schema::dropIfExists('model_ranges');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateRangesTable extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -34,4 +34,4 @@ class CreateRangesTable extends Migration
|
|||
{
|
||||
Schema::dropIfExists('ranges');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProductsTable extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -37,4 +37,4 @@ class CreateProductsTable extends Migration
|
|||
{
|
||||
Schema::dropIfExists('products');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateCustomersTable extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -39,4 +39,4 @@ class CreateCustomersTable extends Migration
|
|||
{
|
||||
Schema::dropIfExists('customers');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateParticipations extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -15,14 +15,25 @@ class CreateParticipations extends Migration
|
|||
{
|
||||
Schema::create('participations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('ip');
|
||||
$table->string('sticker')->nullable();
|
||||
$table->string('ticket')->nullable();
|
||||
$table->string('ip')->comment('Adresse ip de la participation');
|
||||
|
||||
$table->string('sticker')->nullable()->comment('Si gagnant, fichier image du sticker utilisé');
|
||||
$table->string('ticket')->nullable()
|
||||
->comment('Si gagnant, fichier image du ticket de caisse prouvant l\'achat du produit stické');
|
||||
$table->string('barcode')->nullable();
|
||||
$table->foreignId('customer_id')->constrained('customers');
|
||||
$table->foreignId('code_unique_id')->constrained('codes');
|
||||
$table->foreignId('product_id')->nullable()->constrained('products');
|
||||
$table->foreignId('reduction_id')->nullable()->constrained('reductions');
|
||||
|
||||
// * RELATIONSHIPS
|
||||
$table->foreignId('customer_id')->comment('Customer participant')
|
||||
->constrained('customers');
|
||||
$table->foreignId('code_unique_id')->comment('Code unique utilisé')
|
||||
->constrained('codes');
|
||||
$table->foreignId('product_id')->nullable()
|
||||
->comment('Si code EAN activés, Produit porteur de l\'offre (code ean indiqué)')
|
||||
->constrained('products');
|
||||
|
||||
$table->foreignId('discount_id')->nullable()
|
||||
->comment('Bon de réduction gagné')->constrained('discounts');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
@ -36,4 +47,4 @@ class CreateParticipations extends Migration
|
|||
{
|
||||
Schema::dropIfExists('participations');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateInstantWins extends Migration
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -15,11 +15,14 @@ class CreateInstantWins extends Migration
|
|||
{
|
||||
Schema::create('instant_wins', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->dateTime('appear_date');
|
||||
$table->boolean('won')->default(0);
|
||||
$table->foreignId('prize_id')->constrained('prizes');
|
||||
$table->foreignId('participation_id')->nullable()
|
||||
->constrained('participations')->unique();
|
||||
$table->timestamp('available_at')
|
||||
->comment('La date-heure à laquelle l\'instant gagnant pourras être gagné');
|
||||
$table->boolean('won')->default(0)->comment('L\'instant à été gagné ?');
|
||||
|
||||
$table->foreignId('prize_id')->comment('Le lot qui à été gagné')->constrained('prizes');
|
||||
$table->foreignId('participation_id')
|
||||
->comment('Le customer participant qui à gagné avec les informations sur sa participation')
|
||||
->nullable()->constrained('participations')->unique();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -32,4 +35,4 @@ class CreateInstantWins extends Migration
|
|||
{
|
||||
Schema::dropIfExists('instant_wins');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class SettingsSeeder extends Seeder
|
|||
$settings->activated_teaser = false;
|
||||
$settings->activated_close_page = false;
|
||||
$settings->redirect_close = "https://example.test";
|
||||
$settings->reductions_activated = false;
|
||||
$settings->discounts_activated = false;
|
||||
$settings->notification_emails = [];
|
||||
$settings->winning_proof = 0;
|
||||
$settings->web_coupons = [];
|
||||
|
|
|
|||
|
|
@ -264,9 +264,9 @@ return [
|
|||
'redirect_close' => 'url de redirection après la date de fin du jeu',
|
||||
'winning_proof' => 'activer les preuves de gain',
|
||||
'company' => 'société',
|
||||
'reductions_activated' => 'activer les bons de réduction',
|
||||
'reductions_site' => 'référence du site',
|
||||
'reductions_campaign' => 'référence de la campagne',
|
||||
'discounts_activated' => 'activer les bons de réduction',
|
||||
'discounts_site' => 'référence du site',
|
||||
'discounts_campaign' => 'référence de la campagne',
|
||||
'analytics' => 'analytics',
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -17,33 +17,33 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
});
|
||||
}
|
||||
|
||||
const inputReductionsActivated = document.querySelector("input[name=reductions_activated]") as HTMLInputElement | null;
|
||||
const inputDiscountsActivated = document.querySelector("input[name=discounts_activated]") as HTMLInputElement | null;
|
||||
const inputActivatedClosePage = document.querySelector("input[name=activated_close_page]") as HTMLInputElement | null;
|
||||
|
||||
const reductionsSite = document.getElementById("reductions-site") as HTMLElement | null;
|
||||
const reductionsCampaign = document.getElementById("reductions-campaign") as HTMLElement | null;
|
||||
const reductionsWebCoupons = document.getElementById("reductions-web-coupons") as HTMLElement | null;
|
||||
const discountsSite = document.getElementById("discounts-site") as HTMLElement | null;
|
||||
const discountsCampaign = document.getElementById("discounts-campaign") as HTMLElement | null;
|
||||
const discountsWebCoupons = document.getElementById("discounts-web-coupons") as HTMLElement | null;
|
||||
|
||||
const closePageActiveDate = document.getElementById("close-page-active-date");
|
||||
|
||||
const settingsClosePageActiveDate = document.getElementById("settings-close-page-active-date") as HTMLInputElement | null;
|
||||
const settingsReductionsSite = document.getElementById("settings-reductions-site") as HTMLInputElement | null;
|
||||
const settingsReductionsCampaign = document.getElementById("settings-reductions-campaign") as HTMLInputElement | null;
|
||||
const settingsDiscountsSite = document.getElementById("settings-discounts-site") as HTMLInputElement | null;
|
||||
const settingsDiscountsCampaign = document.getElementById("settings-discounts-campaign") as HTMLInputElement | null;
|
||||
|
||||
if (!inputReductionsActivated) {
|
||||
throw new Error("Missing input[name=reductions_activated]");
|
||||
if (!inputDiscountsActivated) {
|
||||
throw new Error("Missing input[name=discounts_activated]");
|
||||
}
|
||||
if (!inputActivatedClosePage) {
|
||||
throw new Error("Missing input[name=activated_close_page]");
|
||||
}
|
||||
if (!reductionsSite) {
|
||||
throw new Error("Missing #reductions-site");
|
||||
if (!discountsSite) {
|
||||
throw new Error("Missing #discounts-site");
|
||||
}
|
||||
if (!reductionsCampaign) {
|
||||
throw new Error("Missing #reductions-campaign");
|
||||
if (!discountsCampaign) {
|
||||
throw new Error("Missing #discounts-campaign");
|
||||
}
|
||||
if (!reductionsWebCoupons) {
|
||||
throw new Error("Missing #reductions-web-coupons");
|
||||
if (!discountsWebCoupons) {
|
||||
throw new Error("Missing #discounts-web-coupons");
|
||||
}
|
||||
if (!closePageActiveDate) {
|
||||
throw new Error("Missing #close-page-active-date");
|
||||
|
|
@ -51,32 +51,32 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
if (!settingsClosePageActiveDate) {
|
||||
throw new Error("Missing #settings-close-page-active-date");
|
||||
}
|
||||
if (!settingsReductionsSite) {
|
||||
throw new Error("Missing #settings-reductions-site");
|
||||
if (!settingsDiscountsSite) {
|
||||
throw new Error("Missing #settings-discounts-site");
|
||||
}
|
||||
if (!settingsReductionsCampaign) {
|
||||
throw new Error("Missing #settings-reductions-campaign");
|
||||
if (!settingsDiscountsCampaign) {
|
||||
throw new Error("Missing #settings-discounts-campaign");
|
||||
}
|
||||
|
||||
const reductionsWebCouponsInputs = reductionsWebCoupons.getElementsByTagName("input");
|
||||
const discountsWebCouponsInputs = discountsWebCoupons.getElementsByTagName("input");
|
||||
|
||||
const toggleReduction = () => {
|
||||
if (!inputReductionsActivated.checked) {
|
||||
reductionsSite.style.display = "none";
|
||||
reductionsCampaign.style.display = "none";
|
||||
reductionsWebCoupons.style.display = "none";
|
||||
settingsReductionsSite.disabled = true;
|
||||
settingsReductionsCampaign.disabled = true;
|
||||
Array.from(reductionsWebCouponsInputs).forEach(element => {
|
||||
const toggleDiscount = () => {
|
||||
if (!inputDiscountsActivated.checked) {
|
||||
discountsSite.style.display = "none";
|
||||
discountsCampaign.style.display = "none";
|
||||
discountsWebCoupons.style.display = "none";
|
||||
settingsDiscountsSite.disabled = true;
|
||||
settingsDiscountsCampaign.disabled = true;
|
||||
Array.from(discountsWebCouponsInputs).forEach(element => {
|
||||
element.disabled = true;
|
||||
});
|
||||
} else {
|
||||
reductionsSite.style.display = "";
|
||||
reductionsCampaign.style.display = "";
|
||||
reductionsWebCoupons.style.display = "";
|
||||
settingsReductionsSite.disabled = false;
|
||||
settingsReductionsCampaign.disabled = false;
|
||||
Array.from(reductionsWebCouponsInputs).forEach(element => {
|
||||
discountsSite.style.display = "";
|
||||
discountsCampaign.style.display = "";
|
||||
discountsWebCoupons.style.display = "";
|
||||
settingsDiscountsSite.disabled = false;
|
||||
settingsDiscountsCampaign.disabled = false;
|
||||
Array.from(discountsWebCouponsInputs).forEach(element => {
|
||||
element.disabled = false;
|
||||
});
|
||||
}
|
||||
|
|
@ -92,9 +92,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
}
|
||||
};
|
||||
|
||||
// Gestion du tableau pour reduction
|
||||
inputReductionsActivated.addEventListener("change", toggleReduction);
|
||||
toggleReduction();
|
||||
// Gestion du tableau pour discount
|
||||
inputDiscountsActivated.addEventListener("change", toggleDiscount);
|
||||
toggleDiscount();
|
||||
|
||||
// Gestion de l'activation de la page de fermeture (champ date à afficher ou non)
|
||||
inputActivatedClosePage.addEventListener("change", toggleClosePage);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<div class="list-group">
|
||||
<span class="list-group-item list-group-item-dark">{{ __('Participation') }}</span>
|
||||
|
||||
@if ($settingsGlobal->reductions_activated)
|
||||
@if ($settingsGlobal->discounts_activated)
|
||||
{{-- WON BR --}}
|
||||
<a class="list-group-item list-group-item-action" href="{{ route('re7.discount') }}"
|
||||
title="{{ __('Afficher un bon de réduction dans un nouvel onglet') }}"
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
<div class="list-group">
|
||||
<span class="list-group-item list-group-item-dark">{{ __('Mails') }}</span>
|
||||
|
||||
@if ($settingsGlobal->reductions_activated)
|
||||
@if ($settingsGlobal->discounts_activated)
|
||||
{{-- WON BR MAIL --}}
|
||||
<a class="list-group-item list-group-item-action" href="{{ route('re7.mail-discount') }}"
|
||||
title="{{ __('Afficher le mail de bon de réduction dans un nouvel onglet') }}"
|
||||
|
|
|
|||
|
|
@ -19,6 +19,6 @@
|
|||
<p><span class="font-weight-bold">{{ __('ID : :id', ['id' => $code->id]) }}</span></p>
|
||||
<p>{{ __('Utilisé ? : :used', ['used' => $code->code_used ? 'OUI' : 'NON']) }}</p>
|
||||
<p>{{ __('Exporté ? : :exported', ['exported' => $code->code_exported ? 'OUI' : 'NON']) }}</p>
|
||||
<p>{{ __('Créé le : :date_creation', ['date_creation' => $code->date_creation]) }}</p>
|
||||
<p>{{ __('Créé le : :date_creation', ['date_creation' => $code->date_creation->isoFormat('DD/MM/YYYY')]) }}</p>
|
||||
@endif
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -330,69 +330,69 @@
|
|||
</h5>
|
||||
|
||||
<div class="row">
|
||||
{{-- REDUCTIONS_ACTIVATED --}}
|
||||
{{-- DISCOUNTS_ACTIVATED --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ Str::ucfirst(__('validation.custom.reductions_activated')) }}</legend>
|
||||
<legend>{{ Str::ucfirst(__('validation.custom.discounts_activated')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@include('back::partials.inputs.tinyint-boolean', [
|
||||
'id' => 'settings-reductions-activated',
|
||||
'label' => Str::ucfirst(__('validation.custom.reductions_activated')),
|
||||
'name' => 'reductions_activated',
|
||||
'id' => 'settings-discounts-activated',
|
||||
'label' => Str::ucfirst(__('validation.custom.discounts_activated')),
|
||||
'name' => 'discounts_activated',
|
||||
'required' => false,
|
||||
'model' => $settingsModel ?? null,
|
||||
'helper' => __('validation.boolean', [
|
||||
'attribute' => Str::ucfirst(__('validation.custom.reductions_activated')),
|
||||
'attribute' => Str::ucfirst(__('validation.custom.discounts_activated')),
|
||||
]),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- REDUCTIONS_SITE --}}
|
||||
<div class="col-12 col-md-6 mb-3" id="reductions-site">
|
||||
{{-- DISCOUNTS_SITE --}}
|
||||
<div class="col-12 col-md-6 mb-3" id="discounts-site">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ Str::ucfirst(__('validation.custom.reductions_site')) }}</legend>
|
||||
<legend>{{ Str::ucfirst(__('validation.custom.discounts_site')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@include('back::partials.inputs.varchar', [
|
||||
'id' => 'settings-reductions-site',
|
||||
'label' => __('validation.custom.reductions_site'),
|
||||
'id' => 'settings-discounts-site',
|
||||
'label' => __('validation.custom.discounts_site'),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'reductions_site',
|
||||
'name' => 'discounts_site',
|
||||
'required' => false,
|
||||
'model' => $settingsModel ?? null,
|
||||
'helper' => __('validation.between.string', [
|
||||
'attribute' => __('validation.custom.reductions_site'),
|
||||
'attribute' => __('validation.custom.discounts_site'),
|
||||
'min' => 3,
|
||||
'max' => 255,
|
||||
]),
|
||||
'placeholder' => __('validation.custom.reductions_site'),
|
||||
'placeholder' => __('validation.custom.discounts_site'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- REDUCTIONS_CAMPAIGN --}}
|
||||
<div class="col-12 col-md-6 mb-3" id="reductions-campaign">
|
||||
{{-- DISCOUNTS_CAMPAIGN --}}
|
||||
<div class="col-12 col-md-6 mb-3" id="discounts-campaign">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ Str::ucfirst(__('validation.custom.reductions_campaign')) }}</legend>
|
||||
<legend>{{ Str::ucfirst(__('validation.custom.discounts_campaign')) }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@include('back::partials.inputs.varchar', [
|
||||
'id' => 'settings-reductions-campaign',
|
||||
'label' => __('validation.custom.reductions_campaign'),
|
||||
'id' => 'settings-discounts-campaign',
|
||||
'label' => __('validation.custom.discounts_campaign'),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'reductions_campaign',
|
||||
'name' => 'discounts_campaign',
|
||||
'required' => false,
|
||||
'model' => $settingsModel ?? null,
|
||||
'helper' => __('validation.between.string', [
|
||||
'attribute' => __('validation.custom.reductions_campaign'),
|
||||
'attribute' => __('validation.custom.discounts_campaign'),
|
||||
'min' => 3,
|
||||
'max' => 255,
|
||||
]),
|
||||
'placeholder' => __('validation.custom.reductions_campaign'),
|
||||
'placeholder' => __('validation.custom.discounts_campaign'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -407,7 +407,7 @@
|
|||
'coupon_height' => 409,
|
||||
];
|
||||
@endphp
|
||||
<div class="web-coupons mb-3" id="reductions-web-coupons" data-json='@json($data)'></div>
|
||||
<div class="web-coupons mb-3" id="discounts-web-coupons" data-json='@json($data)'></div>
|
||||
@include('back::modules.input-error', ['inputName' => 'web_coupons'])
|
||||
@include('back::modules.input-error', ['inputName' => 'web_coupons.*'])
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue