OP BRI Charcuterie

This commit is contained in:
Olivier Legat 2022-03-10 13:31:10 +00:00
parent 7684dcb069
commit 0c4ab4cf89
51 changed files with 1283 additions and 263 deletions

View file

@ -1,36 +1,24 @@
### APPLICATION
APP_NAME="Le Gaulois"
APP_KEY=base64:Q/a3dUg+FqZCtvo+XGDDqntgpvL3B2SQUVlJKi47b+U=
# LOCAL
APP_KEY=
APP_ENV=local
APP_DEBUG=true
APP_URL=http://legaulois2020.test
# DEV
APP_ENV=production
APP_DEBUG=false
APP_URL=https://dev.legaulois.fr
# PROD
APP_ENV=production
APP_DEBUG=false
APP_URL=https://legaulois.fr
APP_URL=
## LOG LEVEL
# LOCAL
LOG_CHANNEL=stack
# DEV, PROD
LOG_CHANNEL=stackProd
## DATABASE
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3307
DB_DATABASE=legaulois2020
DB_USERNAME=root
DB_PORT=3306
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
## DATABASE MIGRATION
DB_DATABASE_2016=legaulois2016
DB_USERNAME_2016=root
DB_USERNAME_2016=
DB_PASSWORD_2016=
## MIGRATION
@ -45,12 +33,12 @@ SESSION_LIFETIME=120
## MAIL
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=8a51f2fab34b77
MAIL_PASSWORD=49de71fa995df4
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=contact@legaulois.fr
MAIL_HOST=
MAIL_PORT=
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=
MAIL_FROM_ADDRESS=no-reply@legaulois.fr
MAIL_FROM_NAME="Contact Le Gaulois (legaulois.fr)"
## MAIL ADDRESSES
@ -62,21 +50,28 @@ MAIL_LIST_PASSERELLE=passerelle.ldc@ldc.fr
BOUTIQUE_ARCHADIA_OP_CODE=16
## CRM
CRM_ENDPOINT=https://ldcldccrm:K5cJmTsG@dev.ldc-crm.fr
CRM_API_TOKEN=bVFrPoNR3pD19xmJEZjrriGKsKINHwTtHJDn9oXVefc5DW5wVwxjvGCaQFgBGlyMPe54p4Ax1LwZ7mng
CRM_ENDPOINT=
CRM_API_TOKEN=
## MES BR
MESBR_REF_SITE=TESTSW
MESBR_REF_CAMP=773
MESBR_ENDPOINT=
MESBR_REF_CAMP=
## OP BR CHARCUT
MESBR_REF_SITE_CHARCUT=
MESBR_REF_CAMP_CHARCUT=
MESBR_COUPON_1_CHARCUT=""
MESBR_COUPON_2_CHARCUT=""
MESBR_COUPON_3_CHARCUT=""
## GOOGLE
ANALYTICS_GOOGLE_ID="UA-30828412-1"
GOOGLE_MAP_API_KEY="AIzaSyBQPBPvZSJmA4bH6rBjf8ybqH-xulDUsBk"
ANALYTICS_GOOGLE_ID=
GOOGLE_MAP_API_KEY=
## MERCANET
MERCANET_SECRET=S9i8qClCnb2CZU3y3Vn0toIOgz3z_aBi79akR30vM9o
MERCANET_MERCHAND_ID=211000021310001
MERCANET_ENV=TEST
MERCANET_SECRET=
MERCANET_MERCHAND_ID=
MERCANET_ENV=
# FUCK THE CRM JUST LOGIN (needs debug mode)
NOCRM=true
# BYPASS THE CRM JUST LOGIN (needs debug mode)
NOCRM=false

View file

@ -1,5 +1,21 @@
# Le Gaulois
## .env
En DEV et PROD mettre :
```
LOG_CHANNEL=stackProd
```
## Flux
Flux INCO dans :
```
storage/inco
```
Flux Tracabilité dans :
```
storage/tracabilite
```
## Scheduled Jobs
- DeleteOrders : daily at 14

View file

@ -84,7 +84,7 @@ class AuthController extends Controller
Utils::sendEmailErrorManually($e);
// Une erreur critique est survenue avec la CRM
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
}//end try
} //end try
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
}
@ -107,18 +107,18 @@ class AuthController extends Controller
} catch (ApiErrorException $e) {
if ($e->getApiError()->equals(ApiError::customerAlreadyActive())) {
return view('front.auth.activate')
->with('message', 'Votre compte est déjà activé, vous pouvez dès à présent vous connecter avec celui-ci.');
->with('message', 'Votre compte est déjà activé, vous pouvez dès à présent vous connecter avec celui-ci.');
}
Utils::sendEmailErrorManually($e);
// Une erreur critique est survenue avec la CRM
return view('front.auth.activate')
->with('message', 'Une erreur est survenue, merci de réessayer ultérieurement.');
->with('message', 'Une erreur est survenue, merci de réessayer ultérieurement.');
} catch (CrmException $e) {
Utils::sendEmailErrorManually($e);
// Une erreur critique est survenue avec la CRM
return view('front.auth.activate')
->with('message', 'Une erreur est survenue, merci de réessayer ultérieurement.');
}//end try
} //end try
return view('front.auth.activate')->with('message', "Ce lien d'activation n'est pas valide.");
}
@ -205,7 +205,7 @@ class AuthController extends Controller
throw $e;
}
Session::push('needCrmInfoUpdate', true);
}//end try
} //end try
// Si pas de compte local mais existe en CRM
if (!$customer) {
@ -219,7 +219,7 @@ class AuthController extends Controller
Utils::sendEmailErrorManually($e);
// Une erreur critique est survenue avec la CRM
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
}//end try
} //end try
}
/**
@ -264,9 +264,9 @@ class AuthController extends Controller
);
default:
Utils::sendEmailErrorManually($e);
// une erreur non gérée
// une erreur non gérée
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
}//end switch
} //end switch
}
/**
@ -366,7 +366,7 @@ class AuthController extends Controller
Utils::sendEmailErrorManually($e);
// Une erreur critique est survenue avec la CRM
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
}//end try
} //end try
}
/**
@ -500,7 +500,7 @@ class AuthController extends Controller
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
} catch (ValidationException $e) {
return back()->withErrors(sprintf('Nouveau mot de passe : %s', $e->getMessage()));
}//end try
} //end try
return back()->with('success', __("Modifications enregistrés !"));
}
}

View file

@ -0,0 +1,138 @@
<?php
namespace App\Http\Controllers\OpBrCharcut;
use App\Http\Requests\OpBrCharcut\ParticipateRequest;
use App\Mail\NotifAdmin;
use App\Mail\ReductionWon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\Controller;
class EnterCodeController extends Controller
{
/**
* Show enter code form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
return view('front.opbrcharcut.enter-code');
}
/**
* Participate Method
*
* @param ParticipateRequest $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function participate(ParticipateRequest $request)
{
return $this->serveCouponWin($request->code);
}
/**
* Détermine si un BR doit être servi
* renvoi la vue de gain BR
*
* @param
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
private function serveCouponWin($code)
{
//ici on a besoin que d'un identifiant pas de tout le coupon
$crmCoupon = $this->updateCoupon(config('opbrcharcut.MESBR_COUPON_1'), 1);
if (!$crmCoupon) {
return back()->withErrors("Une erreur est survenue, merci de réessayez ultérieurement.");
}
$crmCoupon = $this->updateCoupon(config('opbrcharcut.MESBR_COUPON_2'), 2);
if (!$crmCoupon) {
return back()->withErrors("Une erreur est survenue, merci de réessayez ultérieurement.");
}
$crmCoupon = $this->updateCoupon(config('opbrcharcut.MESBR_COUPON_3'), 3);
if (!$crmCoupon) {
return back()->withErrors("Une erreur est survenue, merci de réessayez ultérieurement.");
}
$user = Auth::guard('customer')->user();
Mail::to($user->email)->send(new ReductionWon($user->apiData, $crmCoupon));
//Marquer le code comme utilisé par le user
$code->code_used = 1;
$code->customer()->associate($user);
$code->save();
return view('front.opbrcharcut.reduction', compact('crmCoupon'));
}
/**
* Update a coupon
*
* @param mixed $id_coupon
* @return \App\Models\Reduction|null
*/
private function updateCoupon($id_coupon, $qtty)
{
/** @var \App\Lib\MesBROld */
$mesBRCharc = app('mesBR_Charcut');
/** @var \App\Models\Customers $customer */
$customer = Auth::guard('customer')->user();
/** @var \LDC\LDCCRM\Models\Customer */
$crmCustomer = $customer->apiData;
$updateCustID = $this->updateCustomer(
$crmCustomer->hashcode,
$crmCustomer->email,
$crmCustomer->country
);
if (!$updateCustID) {
return false;
}
$result = $mesBRCharc->updatePanier($crmCustomer, $updateCustID, $id_coupon, $qtty);
if ($result["status"] === "OK") {
//ici on a besoin que savoir que c'était OK
$reduction = $result["link"];
} else {
Mail::to(config('mail.contactsList.serviceweb'))
->send(new NotifAdmin(\sprintf(
'MESBR : Une erreur est survenue. Code : %s Message : %s',
$result["code"],
$result["message"]
)));
return false;
}
return $reduction;
}
private function updateCustomer($hascode, $email, $country)
{
/** @var \App\Lib\MesBR */
$mesBR = app('mesBR');
$updateCust = $mesBR->updateCustomer(
$hascode,
$email,
$country
);
if ($updateCust->status === 'KO') {
Mail::to(config('mail.contactsList.serviceweb'))
->send(new NotifAdmin(\sprintf(
'MESBR : Une erreur est survenue. Code : %s Message : %s',
$updateCust->code,
$updateCust->message
)));
return false;
}
if (!isset($updateCust->customer->id)) {
return $this->updateCustomer($hascode, $email, $country);
}
return $updateCust->customer->id;
}
}

View file

@ -0,0 +1,80 @@
<?php
namespace App\Http\Requests\OpBrCharcut;
use App\Models\OpBrCharcut\Code;
use App\Models\OpBrCharcut\CodeEan;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Str;
class ParticipateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
if (is_string($this->code_ean)) {
$this->merge([
'code_ean' => \in_array(Str::length($this->code_ean), [13, 8, 7]) ?
CodeEan::where('code', $this->code_ean)
->orWhere('code', 'LIKE', Str::limit($this->code_ean, 13, '') . '%')
->orWhere('code', 'LIKE', Str::limit($this->code_ean, 8, '') . '%')
->orWhere('code', 'LIKE', Str::limit($this->code_ean, 7, '') . '%')
->first() : null
]);
}
if (is_string($this->code)) {
$this->merge([
'serial' => $this->code,
'code' => Code::whereId(Code::serialToInt(Str::upper($this->code)))->first() ?? false,
]);
}
return auth()->guard('customer')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = [
'code' => [
'required',
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if (
$value === false or
!\is_object($value) or
\get_class($value) !== Code::class
) {
$fail('Code incorrect, veuillez réessayer.');
return false;
} elseif ($value->code_used === 1) {
$fail('Ce code n\'est plus utilisable.');
return false;
}
// $this->code->code_used = 1;
// $this->code->save();
}
],
'code_ean' => [
'required',
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
if (!\is_object($value) or \get_class($value) !== CodeEan::class) {
$fail('Le code barre entré est incorrect, veuillez réessayer.');
}
}
]
];
return $rules;
}
}

View file

@ -5,7 +5,6 @@ namespace App\Lib;
class MesBR
{
private $endpoint;
private $refCamp;
public function __construct($endpoint, $refCamp)
@ -13,6 +12,7 @@ class MesBR
$this->endpoint = $endpoint;
$this->refCamp = $refCamp;
}
public function createCustomer(string $hashcode, string $email, string $country)
{
return $this->callApi("POST", '/customer', ['hashcode' => $hashcode, 'email' => $email, 'country' => $country]);

129
app/Lib/MesBROld.php Normal file
View file

@ -0,0 +1,129 @@
<?php
namespace App\Lib;
/**
* This class is an old version taken in GGW
* it should not be used anymore once mesBR is upgraded to a stable state
*/
class MesBROld
{
private $endpoint;
private $refSite;
private $refCamp;
public function __construct($endpoint, $refSite, $refCamp)
{
$this->endpoint = $endpoint;
$this->refSite = $refSite;
$this->refCamp = $refCamp;
}
/** Update contact *
* NOT USED - SHOULD BE DELETED
* @param $oCrmUser
* @return bool
*/
public function updateContact($oCrmUser)
{
// dd($oCrmUser);
$datas = [
'refsite' => $this->refSite,
'refadherent' => $oCrmUser->crm_id,
'nom' => $oCrmUser->lastname,
'prenom' => $oCrmUser->firstname,
'email' => $oCrmUser->email,
'date_naissance' => $oCrmUser->birth_date,
'code_postal' => $oCrmUser->postcode,
'commune' => $oCrmUser->city,
'pays' => $this->getCountry($oCrmUser->country),
'hashcode' => $oCrmUser->hashcode
];
$this->callAPI("GET", "/updatecontact", $datas);
// TODO : Verif statut du call ? (Nouvelle API MesBR)
return true;
}
/** Update panier *
* @param $oCrmUser
* @param $couponId
* @param int $quantity
* @return array
*/
public function updatePanier($oCrmUser, $refid, $couponId, $quantity = 1)
{
$datas = [
'refsite' => $this->refSite,
'refcamp' => $this->refCamp,
//TODO : ici il faut une id qui est ajoutée au code barre du coupon donc un hascode c'est trop long
'refadherent' => $refid,
'nom' => $oCrmUser->lastname,
'prenom' => $oCrmUser->firstname,
'email' => $oCrmUser->email,
'code_postal' => $oCrmUser->postcode,
'commune' => $oCrmUser->city,
'pays' => $this->getCountry($oCrmUser->country),
'panier' => "($quantity)$couponId"
];
$res = $this->callAPI("GET", "/updatebasket", $datas);
if (!$res) {
error_log("MESBR - CODE : 999 - MESSAGE : Cannot read API Response (non json)");
return ['status' => 'KO', 'code' => 999, 'message' => 'Cannot read API Response (non json)'];
}
if ($res->Statut === 'KO') {
error_log("MESBR - CODE : $res->Code - MESSAGE : $res->Message");
return ['status' => 'KO', 'code' => $res->Code, 'message' => $res->Message];
}
$panierVerification = $this->endpoint . '/showbasket?basketid=' . $res->Panier->Panier;
$panier_link = $this->endpoint . '/?basketid=' . $res->Panier->Panier;
return ['status' => 'OK', 'link' => $panier_link, 'verif' => $panierVerification, 'basketId' => $res->Panier->Panier];
}
/** Génère le lien vers le mur (ou panier préprogrammé) **/
public function GetMurBDRLink($br_refsite, $br_refcamp, $crmUser)
{
return $this->endpoint . "/?refsite=" . trim($br_refsite) . "&refcamp=" . trim($br_refcamp) . "&email=" . $crmUser->email;
}
private function getCountry($country)
{
switch ($country) {
case 'Belgique':
return 56;
break;
case 'Luxembourg':
return 442;
break;
default:
return 250; //France
break;
}
}
private function callAPI($method, $url, $data)
{
$curl = curl_init();
switch ($method) {
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
curl_setopt($curl, CURLOPT_URL, $this->endpoint . $url);
curl_setopt($curl, CURLOPT_COOKIESESSION, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
if (!$result) {
die("Connection Failure");
}
curl_close($curl);
return json_decode($result);
}
}

37
app/Mail/NotifAdmin.php Normal file
View file

@ -0,0 +1,37 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class NotifAdmin extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
private $msg;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($msg)
{
$this->msg = $msg;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$msg = $this->msg;
return $this->subject(config('app.name') . " : Erreur")->view('front.notif-admin', compact('msg'));
}
}

38
app/Mail/ReductionWon.php Normal file
View file

@ -0,0 +1,38 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ReductionWon extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
private $user, $linkpanier;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($user, $linkpanier)
{
$this->user = $user;
$this->linkpanier = $linkpanier;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->subject($this->user->firstname . ", n'attendez plus pour imprimer vos bon d'achat Le Gaulois !")->view('front.mails.notif-panier')
->with(['user' => $this->user, 'linkpanier' => $this->linkpanier]);
}
}

View file

@ -0,0 +1,82 @@
<?php
namespace App\Models\OpBrCharcut;
use Illuminate\Database\Eloquent\Model;
use Kwaadpepper\Serial\SerialCaster;
use App\Models\Customers;
class Code extends Model
{
protected $table = 'opbrcharcut_codes';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'code_used', 'code_exported',
'date_creation'
];
/**
* Indicates if the model should be timestamped.
*
* @var boolean
*/
public $timestamps = false;
// * RELATIONS
public function customer()
{
return $this->belongsTo(Customers::class);
}
// * FUNCTIONS
/**
* Generate code_unique attribute
*
* @return string|null
*/
public function getCodeUniqueAttribute()
{
if (!$this->id or !\is_integer($this->id) or $this->id < 1) {
return null;
}
return self::intToSerial($this->id);
}
/**
* Generate a serial from an int.
*
* @param integer $int
* @return string The serial
* @throws SerialCasterException If an error happens du to config.
*/
public static function intToSerial(int $int): string
{
return SerialCaster::encode(
$int,
\abs(\crc32(config('app.key'))),
config('opbrcharcut.codeLength'),
config('opbrcharcut.codeCharList')
);
}
/**
* Generate a serial from an int.
*
* @param string $serial
* @return integer The ID represented
* @throws SerialCasterException If an error happens due to config or wrong serial is given.
*/
public static function serialToInt(string $serial): int
{
return SerialCaster::decode(
$serial,
\abs(\crc32(config('app.key'))),
config('opbrcharcut.codeCharList')
);
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Models\OpBrCharcut;
use Illuminate\Database\Eloquent\Model;
class CodeEan extends Model
{
protected $table = 'opbrcharcut_codes_eans';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['code'];
/**
* Indicates if the model should be timestamped.
*
* @var boolean
*/
public $timestamps = false;
}

View file

@ -3,6 +3,7 @@
namespace App\Providers;
use App\Lib\MesBR;
use App\Lib\MesBROld;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ServiceProvider;
@ -21,5 +22,12 @@ class MesBrServiceProvider extends ServiceProvider
config('app.MESBR_REF_CAMP')
);
});
App::singleton('mesBR_Charcut', function () {
return new MesBROld(
config('app.MESBR_ENDPOINT'),
config('opbrcharcut.MESBR_REF_SITE'),
config('opbrcharcut.MESBR_REF_CAMP'),
);
});
}
}

View file

@ -23,6 +23,7 @@
"kwaadpepper/exception-handler": "^0.0.6",
"kwaadpepper/image-resizer": "^0.0.10",
"kwaadpepper/refresh-sitemap": "^0.0.1",
"kwaadpepper/serial-int-caster": "^1.0",
"laravel/framework": "^8.0",
"laravel/tinker": "^2.0",
"laravel/ui": "^3.0",

46
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "853d87d3fbd4a648de146ae43a5e5561",
"content-hash": "9d00c06e433705391e13345c9d064fee",
"packages": [
{
"name": "asm89/stack-cors",
@ -2393,6 +2393,50 @@
},
"time": "2021-09-03T22:42:09+00:00"
},
{
"name": "kwaadpepper/serial-int-caster",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/Kwaadpepper/serial-int-caster.git",
"reference": "bbba003ff5379576f05114386b5ebe8b33bc4705"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Kwaadpepper/serial-int-caster/zipball/bbba003ff5379576f05114386b5ebe8b33bc4705",
"reference": "bbba003ff5379576f05114386b5ebe8b33bc4705",
"shasum": ""
},
"require": {
"php": ">=7.3.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3.6"
},
"type": "library",
"autoload": {
"psr-4": {
"Kwaadpepper\\Serial\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jérémy Munsch",
"email": "github@jeremydev.ovh"
}
],
"description": "Convert int To as serial number and reverse",
"support": {
"issues": "https://github.com/Kwaadpepper/serial-int-caster/issues",
"source": "https://github.com/Kwaadpepper/serial-int-caster/tree/1.0.1"
},
"time": "2021-05-16T15:50:37+00:00"
},
{
"name": "laravel/framework",
"version": "v8.83.2",

View file

@ -114,7 +114,6 @@ return [
|--------------------------------------------------------------------------
*/
'MESBR_REF_SITE' => env('MESBR_REF_SITE'),
'MESBR_REF_CAMP' => env('MESBR_REF_CAMP'),
'MESBR_ENDPOINT' => env('MESBR_ENDPOINT'),

17
config/opbrcharcut.php Normal file
View file

@ -0,0 +1,17 @@
<?php
return [
'MESBR_REF_SITE' => env('MESBR_REF_SITE_CHARCUT'),
'MESBR_REF_CAMP' => env('MESBR_REF_CAMP_CHARCUT'),
'MESBR_COUPON_1' => env('MESBR_COUPON_1_CHARCUT'),
'MESBR_COUPON_2' => env('MESBR_COUPON_2_CHARCUT'),
'MESBR_COUPON_3' => env('MESBR_COUPON_3_CHARCUT'),
// Export pagination.
'paginate' => env('CODE_PAGINATE', 65530),
// Dictionnary of chars to use fo generating unique codes.
'codeCharList' => 'ABCDEFGHJKMNPQRSTUWXYZ123456789',
// Code length.
'codeLength' => 9
];

View file

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateOpbrcharcutCodesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('opbrcharcut_codes', function (Blueprint $table) {
$table->id();
$table->boolean('code_used')->default(0);
$table->foreignId('customer_id')->nullable();
$table->foreign('customer_id')->references('id')->on('customers')->nullOnDelete();
$table->boolean('code_exported')->default(0);
$table->date('date_creation');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('opbrcharcut_codes');
}
}

View file

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateOpbrcharcutCodesEansTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('opbrcharcut_codes_eans', function (Blueprint $table) {
$table->id();
$table->string('code')->unique();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('opbrcharcut_codes_eans');
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

View file

@ -1,10 +1,10 @@
// Breaking Points
$large_screen : 1366px;
$big_screen : 1200px;
$desktop : 1024px;
$tablet : 768px;
$mobile : 500px;
$xmobile : 320px;
$large_screen: 1366px;
$big_screen: 1200px;
$desktop: 1024px;
$tablet: 768px;
$mobile: 500px;
$xmobile: 320px;
@mixin min-width($width) {
@media screen and (min-width: $width), print and (min-width: $width) {
@ -22,7 +22,7 @@ $menuBaseHeight: 5rem;
$menuBreakPoint: $desktop - 24px;
// Typography
$font-family-sans-serif: 'Nunito', sans-serif;
$font-family-sans-serif: "Nunito", sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;
@ -40,8 +40,8 @@ $cyan: #6cb2eb;
$white: #fbf8f5;
$color0: #000;
$primary: #3176C4;
$secondary: #E7374B;
$primary: #3176c4;
$secondary: #e7374b;
$color1: #f3ebe4;
$color2: #07386a;
$color3: #0f437e;
@ -59,19 +59,19 @@ $primary-color: $primary;
$secondary-color: $secondary;
$vegetal: #a2e48b;
$vegetalBodyBG: #8dd175;
$vegetalBodyBG: #8dd175;
$vegetalTitle: #64ab4b;
$pmuColor: #003b22;
// on s'engage
$engagementDarkerGreen: #082014;
$engagementDarkGreen: #006633;
$engagementLightGreen: #8AC51D;
$engagementLightGreen: #8ac51d;
$engagementMajorBreakPoint: $big_screen + 30px;
// Actus
$actuTime: #A29094;
$filterButtonBG: #D0C2B3;
$actuTime: #a29094;
$filterButtonBG: #d0c2b3;
$containerMaxWidth: 77.466rem; // 1162px
$articleMaxWith: 24.4rem; // 366px
$articleMaxHeigth: 40.6rem; // 609px
@ -82,19 +82,19 @@ $imageHeight: 15.865rem; // 238px
$body-bg: $color1;
// Products
$filterSubRangesBg: #E6D6C7;
$filterSubRangesBg: #e6d6c7;
// HEALTH NUTRITION
$healthColor: #ABCCB7;
$healthColor: #abccb7;
// POULTRY PAGE
$subtitleColor: #EE7C28;
$subtitleColor: #ee7c28;
// Breeding Colo
$breedingColor: #366;
// Bourse
$gives: #CF1D40;
$gives: #cf1d40;
$wants: darken(adjust-hue($orange, -5), 10%);
$has: #6cc18a;
$baseMapColor: #4b84c1;
@ -106,8 +106,8 @@ $vintageColor: darken(#e77b32, 10%);
$actualColor: #974c99;
$bgInputColor: #fff;
$textInputColor: #615D5D;
$buttonBgColor: #615D5D;
$textInputColor: #615d5d;
$buttonBgColor: #615d5d;
$tabsTitle: #fff;
$tableHeaderText: $color4;

View file

@ -145,7 +145,6 @@
}
&.entete-white {
&:after {
content: "";
background-image: url("~@/images/commun/entete-tracabilite.svg");
@ -655,7 +654,8 @@
& img {
width: 300px;
}
& > span, > a {
& > span,
> a {
font-family: "Catamaran-Black";
font-size: 1.5em;
text-transform: uppercase;
@ -701,7 +701,7 @@
& .rsmBackLink {
margin-bottom: 0.799rem;
& a {
font-family: 'CreamyScriptRegular';
font-family: "CreamyScriptRegular";
font-size: 2.666rem;
text-decoration: underline;
color: $engagementDarkGreen;
@ -1080,7 +1080,7 @@
padding: 10px 20px;
transform: translateX(-50%) rotate(-7deg);
font-family: "Veneer";
color: white
color: white;
}
& .img-cover {
@ -1782,7 +1782,7 @@
&.sub_testimony {
position: inherit;
&:after{
&:after {
background-size: inherit;
background-position: inherit;
background-image: inherit;
@ -1828,7 +1828,7 @@
overflow: hidden;
position: relative;
.video-bg{
.video-bg {
background-color: #000;
position: absolute;
width: 100%;
@ -1839,10 +1839,10 @@
overflow: hidden;
z-index: -100;
.video-opa{
.video-opa {
opacity: 0.6;
}
.header-bg_video{
.header-bg_video {
position: absolute;
width: 100%;
height: auto;
@ -1855,10 +1855,10 @@
}
}
}
.entete_content-saga{
background-image: url('~@/images/commun/entete.svg');
.entete_content-saga {
background-image: url("~@/images/commun/entete.svg");
background-repeat: no-repeat;
background-position: center 94%;
background-position: center 94%;
background-size: 101% auto;
height: 100%;
width: 100%;
@ -1870,13 +1870,13 @@
}
@include max-width($large_screen) {
background-position: center 88%;
background-position: center 88%;
}
@include max-width($desktop) {
background-position: center 84%;
background-position: center 84%;
}
@include max-width($tablet) {
background-image: none;
background-image: none;
& > h1 {
font-size: 5em;
}
@ -2047,7 +2047,7 @@
}
.sub_header_health_nutrition {
background-image: url('~@/images/sante-nutrition/nutrition_bg.jpg');
background-image: url("~@/images/sante-nutrition/nutrition_bg.jpg");
width: 100%;
margin-top: 70px;
overflow: hidden;

View file

@ -1,11 +1,11 @@
.content.listBR {
text-align: center;
margin-bottom : 4rem !important;
margin-bottom: 4rem !important;
& form {
display: flex;
flex-direction: column;
& >.coupons {
& > .coupons {
display: flex;
flex-direction: column;
margin-top: 2rem;
@ -14,7 +14,7 @@
& > .coupon {
position: relative;
margin: 0 auto;
margin-top : 2rem;
margin-top: 2rem;
user-select: none;
& > label {
@ -26,8 +26,7 @@
}
}
input[type=checkbox] {
input[type="checkbox"] {
position: absolute;
right: 0;
right: 50%;
@ -51,7 +50,7 @@
}
}
input[type=checkbox]:disabled {
input[type="checkbox"]:disabled {
opacity: 0.8;
background-color: gray;
border: 0.2rem solid darken($color: gray, $amount: 30) !important;
@ -61,7 +60,7 @@
box-shadow: none !important;
}
input[type=checkbox]:focus {
input[type="checkbox"]:focus {
outline: none;
border: 0.2rem solid lighten($color: $color5, $amount: 6) !important;
-webkit-box-shadow: none !important;
@ -69,7 +68,7 @@
box-shadow: none !important;
}
input[type=checkbox]:checked {
input[type="checkbox"]:checked {
background-color: darken($color: $color1, $amount: 3);
text-align: center;
line-height: 15px;
@ -89,7 +88,7 @@
&.mobile {
margin-bottom: 6rem;
& input[type=checkbox] {
& input[type="checkbox"] {
position: absolute;
bottom: -4rem;
right: inherit;
@ -113,13 +112,13 @@
min-width: 14rem;
}
}
}
& > .print {
margin-top: 4rem;
& > button {
font-size: 2rem;
height: 3.8rem;
}
& .print {
margin-top: 4rem;
& button {
font-size: 2rem;
height: 3.8rem;
}
}
}

View file

@ -0,0 +1,88 @@
#app > .content.opbr {
text-align: center;
font-family: Catamaran-Regular;
font-size: 1.4rem;
img {
width: 100%;
}
p {
margin: 1rem auto;
}
&.enter-code {
margin: 2rem auto;
@include min-width($tablet) {
margin: 0 auto 4rem;
}
.codes-wrapper {
// width: 80%;
margin: 0 auto;
@include min-width($mobile) {
margin: 0 2rem;
}
@include min-width($tablet) {
display: flex;
align-items: center;
padding: 1rem;
background-color: $opbrImgColor;
}
& > div {
padding: 1rem 0.5rem;
@include min-width($tablet) {
flex: 1;
margin-bottom: 0;
}
}
.codes-img {
background-color: $opbrImgColor;
}
.codes-form {
font-family: Catamaran-Medium;
font-size: 1.9rem;
line-height: 1.1;
color: $opbrFormColor;
background-color: $opbrFormBgColor;
.input-elt {
margin: 2rem 0;
}
h2 {
margin: 0.7rem 0;
color: $opbrFormTitleColor;
font-size: 2rem;
}
input[type="text"] {
width: 90%;
border: none;
border-radius: 7px;
font-size: 1.5rem;
text-align: center;
}
input[type="submit"] {
min-width: min-content;
width: 50%;
height: auto;
border: none;
border-radius: 7px;
font-size: 3rem;
padding: 0.2rem 5rem;
background-color: $opbrFormTitleColor;
color: $opbrFormBgColor;
}
}
}
a {
font-size: 2rem;
height: 3.8rem;
}
form {
font-size: 0.5rem;
}
}
}

View file

@ -0,0 +1,35 @@
#app > .content.opbr.reductions {
img {
padding: 2rem 2rem 0;
max-width: 100%;
@include min-width($tablet) {
padding: 1rem 2.5rem;
}
}
.reductions-wrapper-mobile {
display: block;
@include min-width($tablet) {
display: none;
}
}
.reductions-wrapper-desktop {
display: none;
@include min-width($tablet) {
display: flex;
}
h2 {
font-size: 3vw;
text-decoration: underline;
text-decoration-color: $opbrUnderlign;
margin-bottom: 2rem;
@include min-width($large_screen) {
font-size: 3rem;
}
}
}
}

View file

@ -0,0 +1,39 @@
.sub_header_enter_code,
.sub_header_print_br {
background-image: url("~@/images/opbrcharcut/opbr_banner_mobile.png");
width: 100%;
height: 83vw;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
&::after {
background-image: none;
@include min-width($tablet) {
background-image: url("~@/images/entete.svg");
}
}
@include min-width($tablet) {
height: 44em;
background-size: cover;
background-image: url("~@/images/opbrcharcut/opbr_banner.jpg");
}
& .title {
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
margin: 6rem 0 0;
width: 100%;
font-size: 1.2em;
& h1 {
color: white;
text-align: center;
font-family: "Veneer";
}
}
}

View file

@ -0,0 +1,6 @@
// OP BR
$opbrImgColor: #f9fafa;
$opbrFormColor: #f3ebe4;
$opbrFormTitleColor: #fff200;
$opbrFormBgColor: #00acef;
$opbrUnderlign: #ffca00;

View file

@ -0,0 +1,4 @@
@import "variables";
@import "subheader";
@import "enter-code";
@import "reductions";

View file

@ -88,3 +88,5 @@
@import "front/pages/onsengage/bloc3";
@import "front/pages/onsengage/bloc4";
@import "front/pages/onsengage/bloc5";
@import "front/pages/opbrcharcut/all";

View file

@ -0,0 +1,73 @@
<html>
<head>
<meta charset="utf-8">
<title>Imprimer mes bons d'achats</title>
</head>
<body>
<table style="font-family: arial; font-size: 16px;" width="600" align="center" cellpadding="0" cellspacing="0" bgcolor="#ffffff">
<tr style="background-color: #0f437e;">
<td valign="top" style="border:none; margin:0;">
<a target="_blank" href="{{ route('club.index') }}" style="color:white; text-decoration:none;">
<img src="{{ asset('assets/images/mail/header-1.jpg') }}" width="215" height="35" style="border:none; margin:0; display:block;" alt="Le Gaulois"/>
</a>
</td>
<td valign="top" style="border:none; margin:0;">
<a target="_blank" href="{{ route('products.index') }}" style="color:white; text-decoration:none;">
<img src="{{ asset('assets/images/mail/header-2.jpg') }}" width="105" height="35" style="border:none; margin:0; display:block;" alt="Les produits"/>
</a>
</td>
<td valign="top" style="border:none; margin:0;">
<a target="_blank" href="{{ route('kitchen-side.index') }}" style="color:white; text-decoration:none;">
<img src="{{ asset('assets/images/mail/header-3.jpg') }}" width="90" height="35" style="border:none; margin:0; display:block;" alt="C&ocirc;t&eacute; cuisine"/>
</a>
</td>
<td valign="top" style="border:none; margin:0;">
<a target="_blank" href="{{ route('brand.index') }}" style="color:white; text-decoration:none;">
<img src="{{ asset('assets/images/mail/header-4.jpg') }}" width="80" height="35" style="border:none; margin:0; display:block;" alt="La marque"/>
</a>
</td>
</tr>
<tr style="background-color: #0f437e;">
<td valign="top" style="border:none; margin:0; text-align:center;" colspan="5" >
<a target="_blank" href="{{ route('club.index') }}" style="color:white; text-decoration:none;">
<img src="{{ asset('assets/images/mail/header-club.jpg') }}" width="600" height="205" style="border:none; margin:0; display:block;" alt="Le Club Le Gaulois"/>
</a>
</td>
</tr>
<tr>
<td valign="top" style="border:none; margin:0; text-align:center; color:#e10f21; font-size:20px;" colspan="5">
<h1> Profitez de vos bons d'achat </h1>
</td>
</tr>
<tr>
<td valign="top" style="border:none; margin:0; text-align:center;" colspan="5">
<p>Bonjour{{ $user->firstname !== null ? " " . $user->firstname : null }},</p>
<p>Vous venez de créditer des bons d'achat sur votre compte <strong>le club des Gaulois</strong>!</p>
<br>
<p>Pour imprimez vos bons : <br><a href="{{ $linkpanier }}">Cliquez ici</a>.</p>
</td>
</tr>
<tr>
<td valign="top" style="border:none; margin:0; text-align:right;" colspan="5">
<p style="margin-right:20px;">Gauloisement v&ocirc;tre,<br/>L’&eacute;quipe Le Gaulois</p>
<img src="{{ asset('assets/images/mail/spacer.gif') }}" width="600" height="20" style="border:none; margin:0; display:block;" alt=""/>
</td>
</tr>
<tr style="background-color: #0f437e;">
<td valign="top" style="border:none; margin:0;" ></td>
<td valign="top" style="border:none; margin:0;" >
<a target="_blank" href="{{ route('club.index') }}" style="color:white; text-decoration:none;">
<img src="{{ asset('assets/images/mail/footer-logo.jpg') }}" width="105" height="78" style="border:none; margin:0; display:block;" alt="Le Club Le Gaulois"/>
</a>
</td>
<td valign="top" style="border:none; margin:0;" >
<a target="_blank" href="https://www.facebook.com/LeGauloisFrance/" style="color:white; text-decoration:none;">
<img src="{{ asset('assets/images/mail/footer-fb.jpg') }}" width="90" height="78" style="border:none; margin:0; display:block;" alt="Facebook"/>
</a>
</td>
<td valign="top" style="border:none; margin:0;" ></td>
<td valign="top" style="border:none; margin:0;" ></td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,2 @@
<p>Bonjour,</p>
<p>{{ $msg }}</p>

View file

@ -0,0 +1,47 @@
@extends('layouts.app')
@section('title', __('Bons de réduction de la gamme Charcuterie Le Gaulois'))
@section('description', "Gagner des bons de réductions de la gamme Charcuterie Le Gaulois")
@section('sub_header')
<div class="sub_header sub_header_enter_code"></div>
@endsection
@section('content')
<div class="content enter-code opbr">
@auth('customer')
<div class="codes-wrapper">
<div class="codes-img">
<img src="{{ asset('assets/images/opbrcharcut/img-BR.png') }}" alt="{{ __('Bon de réduction de 3€ - Offre découverte') }}">
</div>
<div class="codes-form">
<p>Pour télécharger vos webcoupons, veuillez renseigner les champs suivants&nbsp;:</p>
<form id="code_form" method="POST" action="{{route('opbrcharcut.participate')}}">
@csrf
<div class="input-elt edit">
<h2>Saisissez le code présent sur le sticker</h2>
<input type="text" name="code" id="code" required minlength="9" maxlength="9">
</div>
<div class="input-elt edit">
<h2>Saisissez le code barre du produit acheté</h2>
<input type="text" name="code_ean" id="code_ean" required minlength="6" maxlength="13">
</div>
<div class="input-elt validate">
<input type="submit" class="btn btn-white btn-veneer-txt" value="{{ __('Valider') }}">
</div>
</form>
</div>
</div>
@else
<p>Pour profiter des bons de réduction, merci de vous connecter à votre compte Le Gaulois.</p>
<a href="{{ route('form-connexion') }}" class="btn btn-white btn-veneer-txt">Connexion</a>
@endauth
@if ($errors->any())
<div class="errors">
<i class="fa fa-exclamation-triangle"></i>
@foreach ($errors->all() as $error)
<p class="error">• {{ $error }}</p>
@endforeach
</div>
@endif
</div>
@endsection

View file

@ -0,0 +1,48 @@
@extends('layouts.app')
@section('title', __('Bons de réduction de la gamme Charcuterie Le Gaulois'))
@section('description', "Gagner des bons de réductions de la gamme Charcuterie Le Gaulois")
@section('sub_header')
<div class="sub_header @if(isset($white))entete-white @endif sub_header_print_br"></div>
@endsection
@section('content')
<div class="content opbr reductions listBR print-br">
{{-- <h2>Cliquez sur le lien ci-dessous pour imprimer vos bons</h2> --}}
<a href="#print">
<div class="br-wrapper">
<div class="reductions-wrapper-desktop">
<div class="charcut-bloc">
<h2>les offres charcuterie le Gaulois</h2>
<img src="{{ asset('assets/images/opbrcharcut/Charcut-1-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme Charcuterie Le Gaulois') }}">
<img src="{{ asset('assets/images/opbrcharcut/Charcut-2-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme Charcuterie Le Gaulois') }}">
<img src="{{ asset('assets/images/opbrcharcut/Charcut-3-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme Charcuterie Le Gaulois') }}">
</div>
<div class="charcut-bloc">
<h2>les offres panés le Gaulois</h2>
<img src="{{ asset('assets/images/opbrcharcut/Panne-1-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme des Panés Le Gaulois') }}">
<img src="{{ asset('assets/images/opbrcharcut/Panne-2-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme des Panés l\'Authentique') }}">
<img src="{{ asset('assets/images/opbrcharcut/Panne-3-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme des Panés Le Gaulois') }}">
</div>
</div>
<div class="reductions-wrapper-mobile">
<img src="{{ asset('assets/images/opbrcharcut/Mobile-Charcut-1-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme Charcuterie Le Gaulois') }}">
<img src="{{ asset('assets/images/opbrcharcut/Mobile-Charcut-2-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme Charcuterie Le Gaulois') }}">
<img src="{{ asset('assets/images/opbrcharcut/Mobile-Charcut-3-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme Charcuterie Le Gaulois') }}">
<img src="{{ asset('assets/images/opbrcharcut/Mobile-Pane-1-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme des Panés Le Gaulois') }}">
<img src="{{ asset('assets/images/opbrcharcut/Mobile-Pane-2-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme des Panés l\'Authentique') }}">
<img src="{{ asset('assets/images/opbrcharcut/Mobile-Pane-3-imprim.png') }}" alt="{{ __('Bon de réduction - Gamme des Panés Le Gaulois') }}">
</div>
</div>
</a>
<div class="print" id="print">
<a href="{{ $crmCoupon }}" target="_blank">
<button class="btn btn-white btn-veneer-txt">{{ __('Imprimer') }}</button>
</a>
<br><br>
<a href="{{ route('club.index') }}">
<button class="btn btn-white btn-veneer-txt">{{ __('Aller dans le Club') }}</button>
</a>
</div>
</div>
@endsection

View file

@ -11,6 +11,7 @@ use App\Http\Controllers\ClubController;
use App\Http\Controllers\ContactController;
use App\Http\Controllers\CustomerController;
use App\Http\Controllers\EngagementsController;
use App\Http\Controllers\OpBrCharcut\EnterCodeController;
use App\Http\Controllers\FaqController;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\KitchenSideController;
@ -58,21 +59,21 @@ Route::view('/mentions-legales', 'front.legals')->name('legal-notice');
Route::view('/charte-de-confidentialite', 'front.charte')->name('chart-conf');
Route::prefix('/produits')
->name('products.')
->group(function () {
Route::get('/', [ProductsController::class, 'index'])->name('index');
Route::get('/gamme/{slugRange}/{subRange?}', [ProductsController::class, 'filter'])->name('range');
Route::get('/moment-consommations/{slugConsumptionTime}', [ProductsController::class, 'filter'])
->name('consumption-times');
Route::get('/type-viande/{slugMeatType}', [ProductsController::class, 'filter'])->name('meat-type');
Route::get('/label/{slugLabel}', [ProductsController::class, 'filter'])->name('label');
});
->name('products.')
->group(function () {
Route::get('/', [ProductsController::class, 'index'])->name('index');
Route::get('/gamme/{slugRange}/{subRange?}', [ProductsController::class, 'filter'])->name('range');
Route::get('/moment-consommations/{slugConsumptionTime}', [ProductsController::class, 'filter'])
->name('consumption-times');
Route::get('/type-viande/{slugMeatType}', [ProductsController::class, 'filter'])->name('meat-type');
Route::get('/label/{slugLabel}', [ProductsController::class, 'filter'])->name('label');
});
Route::prefix('/produit')
->name('product.')
->group(function () {
Route::get('/{product}', [ProductsController::class, 'show'])->name('show');
});
->name('product.')
->group(function () {
Route::get('/{product}', [ProductsController::class, 'show'])->name('show');
});
Route::prefix('/cote-cuisine')->name('kitchen-side.')->group(function () {
Route::get('/', [RecipesController::class, 'kitchenside'])->name('index');
@ -103,53 +104,53 @@ Route::prefix('/cote-cuisine')->name('kitchen-side.')->group(function () {
'/cote-cuisine/sante-et-nutrition/qualite-nutritionelle-le-gaulois-s-engage'
)->name('index');
Route::get('/bienfaits-nutritionnels-de-la-volaille', [KitchenSideController::class, 'nutritionPoultry'])
->name('nutrition-poultry');
->name('nutrition-poultry');
Route::get('/qualite-nutritionelle-le-gaulois-s-engage', [KitchenSideController::class, 'nutritionQuality'])
->name('nutrition-quality');
->name('nutrition-quality');
});
});
Route::prefix('/recettes')
->name('recipes.')
->group(function () {
Route::get('/proposer-une-recette', [ContactController::class, 'proposeRecipe'])->name('propose');
Route::post('/rate/{recipe:slug}', [RecipesController::class, 'rate'])->name('rate');
Route::get('/{recipe:slug}', [RecipesController::class, 'show'])->name('show');
Route::get('/{type?}/{value?}', [RecipesController::class, 'index'])->name('index');
});
->name('recipes.')
->group(function () {
Route::get('/proposer-une-recette', [ContactController::class, 'proposeRecipe'])->name('propose');
Route::post('/rate/{recipe:slug}', [RecipesController::class, 'rate'])->name('rate');
Route::get('/{recipe:slug}', [RecipesController::class, 'show'])->name('show');
Route::get('/{type?}/{value?}', [RecipesController::class, 'index'])->name('index');
});
Route::prefix('/la-marque')
->name('brand.')
->group(function () {
Route::get('/', [BrandController::class, 'index'])->name('index');
Route::get('/saga-publicitaire', [BrandController::class, 'ads'])->name('pub');
Route::get('/tracabilite/search', [TraceabilityController::class, 'search'])->name('traceability-search');
Route::view('/notre-histoire', 'front.brand.history')->name('history');
// redirections Lot2
Route::redirect('/tracabilite', '/la-marque/eleveurs-engagés', 301);
Route::redirect('/nos-engagements-qualite', '/la-marque/production-tracable', 301);
Route::get('/eleveurs-engagés', [BrandController::class, 'engage'])->name('engage');
Route::get('/production-tracable', [BrandController::class, 'tracable'])->name('tracable');
Route::view('/volailles-francaises', 'front.brand.poultry-page.poultry')->name('poultry');
Route::prefix('/actualites')
->name('news.')
->name('brand.')
->group(function () {
Route::get('/renderActu/{publishedActu}', [ActuController::class, 'renderActu'])->name('renderActu');
Route::get('/{publishedActu}', [ActuController::class, 'view'])->name('show');
Route::get('/', [ActuController::class, 'index'])->name('index');
Route::get('/', [BrandController::class, 'index'])->name('index');
Route::get('/saga-publicitaire', [BrandController::class, 'ads'])->name('pub');
Route::get('/tracabilite/search', [TraceabilityController::class, 'search'])->name('traceability-search');
Route::view('/notre-histoire', 'front.brand.history')->name('history');
// redirections Lot2
Route::redirect('/tracabilite', '/la-marque/eleveurs-engagés', 301);
Route::redirect('/nos-engagements-qualite', '/la-marque/production-tracable', 301);
Route::get('/eleveurs-engagés', [BrandController::class, 'engage'])->name('engage');
Route::get('/production-tracable', [BrandController::class, 'tracable'])->name('tracable');
Route::view('/volailles-francaises', 'front.brand.poultry-page.poultry')->name('poultry');
Route::prefix('/actualites')
->name('news.')
->group(function () {
Route::get('/renderActu/{publishedActu}', [ActuController::class, 'renderActu'])->name('renderActu');
Route::get('/{publishedActu}', [ActuController::class, 'view'])->name('show');
Route::get('/', [ActuController::class, 'index'])->name('index');
});
});
});
Route::prefix('/oui-cest-bon')
->name('ocb.')
->group(function () {
Route::get('/eleveurs/{breeder}', [OCBController::class, 'breeder'])->name('breeders');
Route::get('/temoignages-eleveurs', [OCBController::class, 'testimonials'])->name('testimonials');
Route::get('/volaille', [OCBController::class, 'poultry'])->name('poultry');
Route::get('/volaille', [OCBController::class, 'poultry'])->name('poultry');
Route::get('/oeuf', [OCBController::class, 'egg'])->name('egg');
Route::view('/', 'front.ocb.index')->name('index');
});
->name('ocb.')
->group(function () {
Route::get('/eleveurs/{breeder}', [OCBController::class, 'breeder'])->name('breeders');
Route::get('/temoignages-eleveurs', [OCBController::class, 'testimonials'])->name('testimonials');
Route::get('/volaille', [OCBController::class, 'poultry'])->name('poultry');
Route::get('/volaille', [OCBController::class, 'poultry'])->name('poultry');
Route::get('/oeuf', [OCBController::class, 'egg'])->name('egg');
Route::view('/', 'front.ocb.index')->name('index');
});
Route::get('/map/breeders', [MapController::class, 'breeders'])->name('map.breeders');
@ -158,47 +159,47 @@ Route::get('/nous-rejoindre', [HomeController::class, 'joinUs'])->name('joinus')
Route::view('/frame/{type}', 'front.frame')->name('front.frame');
Route::prefix('/on-s-engage')
->name('onsengage.')
->group(function () {
Route::prefix('/le-gaulois-marque-engagee-et-responsable')
->name('marqueengage.')
->name('onsengage.')
->group(function () {
// Onglet 100% Française
Route::get(
'/la-grande-marque-alimentaire-francaise',
[EngagementsController::class, 'lagrandemarque']
)->name('lagrandemarque');
// Onglet Bien nourrir
Route::get(
'/bien-nourrir-tous-les-francais',
[EngagementsController::class, 'biennourrir']
)->name('biennourrir');
// Onglet Elever durablement
Route::get(
'/elever-durablement',
[EngagementsController::class, 'eleverdurablement']
)->name('eleverdurablement');
// Onglet Restecpter la terre ^^
Route::get(
'/respecter-la-terre',
[EngagementsController::class, 'respecterlaterre']
)->name('respecterlaterre');
// Onglet Mieux vivre ensemble
Route::get(
'/favoriser-le-mieux-vivre-ensemble',
[EngagementsController::class, 'vivreensemble']
)->name('vivreensemble');
Route::prefix('/le-gaulois-marque-engagee-et-responsable')
->name('marqueengage.')
->group(function () {
// Onglet 100% Française
Route::get(
'/la-grande-marque-alimentaire-francaise',
[EngagementsController::class, 'lagrandemarque']
)->name('lagrandemarque');
// Onglet Bien nourrir
Route::get(
'/bien-nourrir-tous-les-francais',
[EngagementsController::class, 'biennourrir']
)->name('biennourrir');
// Onglet Elever durablement
Route::get(
'/elever-durablement',
[EngagementsController::class, 'eleverdurablement']
)->name('eleverdurablement');
// Onglet Restecpter la terre ^^
Route::get(
'/respecter-la-terre',
[EngagementsController::class, 'respecterlaterre']
)->name('respecterlaterre');
// Onglet Mieux vivre ensemble
Route::get(
'/favoriser-le-mieux-vivre-ensemble',
[EngagementsController::class, 'vivreensemble']
)->name('vivreensemble');
});
});
});
Route::prefix(Str::slug(GeneralConfig::where('type', GeneralConfigType::breedingPage())
->first()->data['breeding_header_title']['value']))
->name('breeding-page.')
->group(function () {
Route::get('/', [BreedingPageController::class, 'index'])->name('index');
Route::get('/{breeding_page_type}', [BreedingPageController::class, 'list'])->name('list');
Route::get('/{breeding_page_type}/{publishedBreedingPage}', [BreedingPageController::class, 'show'])->name('show');
});
->first()->data['breeding_header_title']['value']))
->name('breeding-page.')
->group(function () {
Route::get('/', [BreedingPageController::class, 'index'])->name('index');
Route::get('/{breeding_page_type}', [BreedingPageController::class, 'list'])->name('list');
Route::get('/{breeding_page_type}/{publishedBreedingPage}', [BreedingPageController::class, 'show'])->name('show');
});
// Unsubscribe from newsletter
Route::get('/{unsubscribe}', [CustomerController::class, 'unscribeNewsletter'])
@ -230,87 +231,90 @@ Route::post('/contactez-nous', [ContactController::class, 'contactSubmit'])->nam
Route::post('/reclamation-produit', [ContactController::class, 'complainSubmit'])->name('product-request.submit');
Route::prefix('/le-club-des-gaulois')
->name('club.')
->group(function () {
Route::get('/les-infos-du-club/{articleTag}/{publishedArticle}', [ClubController::class, 'article'])
->name('infos.child');
Route::post('/les-infos-du-club/repondre-sondage', [ClubController::class, 'answerSurvey'])
->name('infos.answer-survey');
Route::prefix('/la-bourse-aux-echanges')
->name('bourse.')
->middleware('auth:customer')
->name('club.')
->group(function () {
Route::get('/', [BourseController::class, 'bourse'])->name('index');
Route::post('/save-state/{type}', [BourseController::class, 'bourseSaveState'])->name('saveState');
Route::post('/search/{type}', [BourseController::class, 'bourseSearch'])->name('search');
Route::get('/les-infos-du-club/{articleTag}/{publishedArticle}', [ClubController::class, 'article'])
->name('infos.child');
Route::post('/les-infos-du-club/repondre-sondage', [ClubController::class, 'answerSurvey'])
->name('infos.answer-survey');
Route::prefix('/la-bourse-aux-echanges')
->name('bourse.')
->middleware('auth:customer')
->group(function () {
Route::get('/', [BourseController::class, 'bourse'])->name('index');
Route::post('/save-state/{type}', [BourseController::class, 'bourseSaveState'])->name('saveState');
Route::post('/search/{type}', [BourseController::class, 'bourseSearch'])->name('search');
});
Route::get('/les-promos', [ClubController::class, 'reductions'])->name('reductions')
->middleware('auth:customer');
Route::post('/les-promos/get', [ClubController::class, 'reductionsGet'])->name('reductionsGet')
->middleware('auth:customer');
Route::prefix('/la-boutique')
->middleware('auth:customer')
// Il faut être connecté pour acceder à la boutique
->name('boutique.')
->group(function () {
Route::get('/', [BoutiqueController::class, 'index'])->name('index');
Route::post('/validation', [BoutiqueController::class, 'validateBuy'])->name('validate');
Route::prefix('commande')
->group(function () {
Route::get('{order}/valide', [BoutiqueController::class, 'validatedBuy'])->name('validated');
Route::get('{order}/reglement', [BoutiqueController::class, 'payWithCb'])->name('payementCB');
});
Route::prefix('/reglement')
->name('reglement.')
->group(function () {
Route::post('/{order}/confirmServ', [BoutiqueController::class, 'confirmCbFromMercanet'])
->name('payementConfirmCBServ')->withoutMiddleware([
'auth:customer',
Authenticate::class,
AddQueuedCookiesToResponse::class,
EncryptCookies::class,
VerifyCsrfToken::class,
StartSession::class,
ShareErrorsFromSession::class,
XssSanitizer::class,
]);
Route::post('/{order}/confirm', [BoutiqueController::class, 'confirmCb'])
->name('payementConfirmCB')->withoutMiddleware([
'auth:customer',
Authenticate::class,
AddQueuedCookiesToResponse::class,
EncryptCookies::class,
VerifyCsrfToken::class,
StartSession::class,
ShareErrorsFromSession::class,
XssSanitizer::class,
]);
});
});
Route::get('/les-infos-du-club/{articleTag}', [ClubController::class, 'index'])->name('indexByCategory');
Route::get('/', [ClubController::class, 'index'])->name('index');
});
Route::get('/les-promos', [ClubController::class, 'reductions'])->name('reductions')
->middleware('auth:customer');
Route::post('/les-promos/get', [ClubController::class, 'reductionsGet'])->name('reductionsGet')
->middleware('auth:customer');
Route::prefix('/la-boutique')
->middleware('auth:customer')
// Il faut être connecté pour acceder à la boutique
->name('boutique.')
->group(function () {
Route::get('/', [BoutiqueController::class, 'index'])->name('index');
Route::post('/validation', [BoutiqueController::class, 'validateBuy'])->name('validate');
Route::prefix('commande')
->group(function () {
Route::get('{order}/valide', [BoutiqueController::class, 'validatedBuy'])->name('validated');
Route::get('{order}/reglement', [BoutiqueController::class, 'payWithCb'])->name('payementCB');
});
Route::prefix('/reglement')
->name('reglement.')
->group(function () {
Route::post('/{order}/confirmServ', [BoutiqueController::class, 'confirmCbFromMercanet'])
->name('payementConfirmCBServ')->withoutMiddleware([
'auth:customer',
Authenticate::class,
AddQueuedCookiesToResponse::class,
EncryptCookies::class,
VerifyCsrfToken::class,
StartSession::class,
ShareErrorsFromSession::class,
XssSanitizer::class,
]);
Route::post('/{order}/confirm', [BoutiqueController::class, 'confirmCb'])
->name('payementConfirmCB')->withoutMiddleware([
'auth:customer',
Authenticate::class,
AddQueuedCookiesToResponse::class,
EncryptCookies::class,
VerifyCsrfToken::class,
StartSession::class,
ShareErrorsFromSession::class,
XssSanitizer::class,
]);
});
});
Route::get('/les-infos-du-club/{articleTag}', [ClubController::class, 'index'])->name('indexByCategory');
Route::get('/', [ClubController::class, 'index'])->name('index');
});
Route::prefix('/mon-compte')
->name('account.')
->middleware('auth:customer')
->group(function () {
Route::get('/infos-manquantes', [ClubController::class, 'missingCrmInfos'])->name('missingCrmInfos');
Route::post('/infos-manquantes', [ClubController::class, 'missingCrmInfosSubmit'])->name('missingCrmInfosSubmit');
Route::get('/liste-de-courses', [ClubController::class, 'cart'])->name('cart');
Route::get('/mes-informations', [ClubController::class, 'infos'])->name('infos');
Route::get('/messages', [ClubController::class, 'messages'])->name('messages');
Route::get('/messages/report', [ContactController::class, 'reportCustomer'])->name('reportCustomer');
Route::get('/notifications', [ClubController::class, 'notifications'])->name('notifications');
Route::get('/recettes-favorites', [ClubController::class, 'favoritesRecipes'])->name('favs-recipes');
Route::post('/liste-de-courses/{product}/{status}', [CustomerController::class, 'setItemInCart'])->name('set-cart');
Route::post('/mes-informations', [ClubController::class, 'updateInfos'])->name('update-infos');
Route::post('/mes-informations/change-password', [AuthController::class, 'changePasswordWhenAuthenticated'])
->name('change-password');
Route::post('/messages/block/{status}', [ClubController::class, 'blockCustomer'])->name('blockCustomer');
Route::post('/messages/delete', [ClubController::class, 'deleteMessage'])->name('deleteMessage');
Route::post('/messages/send', [ClubController::class, 'sendMessage'])->name('sendMessage');
Route::post('/recettes-favorites/{recipe}/set-status/{status}', [CustomerController::class, 'setFavoriteRecipe'])
->name('set-favs-recipes');
Route::redirect('/', '/mon-compte/mes-informations');
});
->name('account.')
->middleware('auth:customer')
->group(function () {
Route::get('/infos-manquantes', [ClubController::class, 'missingCrmInfos'])->name('missingCrmInfos');
Route::post('/infos-manquantes', [ClubController::class, 'missingCrmInfosSubmit'])->name('missingCrmInfosSubmit');
Route::get('/liste-de-courses', [ClubController::class, 'cart'])->name('cart');
Route::get('/mes-informations', [ClubController::class, 'infos'])->name('infos');
Route::get('/messages', [ClubController::class, 'messages'])->name('messages');
Route::get('/messages/report', [ContactController::class, 'reportCustomer'])->name('reportCustomer');
Route::get('/notifications', [ClubController::class, 'notifications'])->name('notifications');
Route::get('/recettes-favorites', [ClubController::class, 'favoritesRecipes'])->name('favs-recipes');
Route::post('/liste-de-courses/{product}/{status}', [CustomerController::class, 'setItemInCart'])->name('set-cart');
Route::post('/mes-informations', [ClubController::class, 'updateInfos'])->name('update-infos');
Route::post('/mes-informations/change-password', [AuthController::class, 'changePasswordWhenAuthenticated'])
->name('change-password');
Route::post('/messages/block/{status}', [ClubController::class, 'blockCustomer'])->name('blockCustomer');
Route::post('/messages/delete', [ClubController::class, 'deleteMessage'])->name('deleteMessage');
Route::post('/messages/send', [ClubController::class, 'sendMessage'])->name('sendMessage');
Route::post('/recettes-favorites/{recipe}/set-status/{status}', [CustomerController::class, 'setFavoriteRecipe'])
->name('set-favs-recipes');
Route::redirect('/', '/mon-compte/mes-informations');
});
Route::get('/boncharcuterie', [EnterCodeController::class, 'index'])->name('opbrcharcut.saisir-code');
Route::post('/boncharcuterie', [EnterCodeController::class, 'participate'])->name('opbrcharcut.participate');