diff --git a/.env.example b/.env.example index d7f83452..c1d15314 100644 --- a/.env.example +++ b/.env.example @@ -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 diff --git a/README.md b/README.md index c63eccac..aedd0cb2 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index fef26be4..f150fdb6 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -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 !")); } } diff --git a/app/Http/Controllers/OpBrCharcut/EnterCodeController.php b/app/Http/Controllers/OpBrCharcut/EnterCodeController.php new file mode 100644 index 00000000..0f266a85 --- /dev/null +++ b/app/Http/Controllers/OpBrCharcut/EnterCodeController.php @@ -0,0 +1,138 @@ +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; + } +} diff --git a/app/Http/Requests/OpBrCharcut/ParticipateRequest.php b/app/Http/Requests/OpBrCharcut/ParticipateRequest.php new file mode 100644 index 00000000..adf37938 --- /dev/null +++ b/app/Http/Requests/OpBrCharcut/ParticipateRequest.php @@ -0,0 +1,80 @@ +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; + } +} diff --git a/app/Lib/MesBR.php b/app/Lib/MesBR.php index 926bbae4..a704dc4e 100644 --- a/app/Lib/MesBR.php +++ b/app/Lib/MesBR.php @@ -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]); diff --git a/app/Lib/MesBROld.php b/app/Lib/MesBROld.php new file mode 100644 index 00000000..5dbe9d51 --- /dev/null +++ b/app/Lib/MesBROld.php @@ -0,0 +1,129 @@ +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); + } +} diff --git a/app/Mail/NotifAdmin.php b/app/Mail/NotifAdmin.php new file mode 100644 index 00000000..8a5af7fa --- /dev/null +++ b/app/Mail/NotifAdmin.php @@ -0,0 +1,37 @@ +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')); + } +} diff --git a/app/Mail/ReductionWon.php b/app/Mail/ReductionWon.php new file mode 100644 index 00000000..365595b4 --- /dev/null +++ b/app/Mail/ReductionWon.php @@ -0,0 +1,38 @@ +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]); + } +} diff --git a/app/Models/OpBrCharcut/Code.php b/app/Models/OpBrCharcut/Code.php new file mode 100644 index 00000000..ced9ba1b --- /dev/null +++ b/app/Models/OpBrCharcut/Code.php @@ -0,0 +1,82 @@ +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') + ); + } +} diff --git a/app/Models/OpBrCharcut/CodeEan.php b/app/Models/OpBrCharcut/CodeEan.php new file mode 100644 index 00000000..d0695f05 --- /dev/null +++ b/app/Models/OpBrCharcut/CodeEan.php @@ -0,0 +1,23 @@ +=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", diff --git a/config/app.php b/config/app.php index 88c2a9d9..03ba59ea 100644 --- a/config/app.php +++ b/config/app.php @@ -114,7 +114,6 @@ return [ |-------------------------------------------------------------------------- */ - 'MESBR_REF_SITE' => env('MESBR_REF_SITE'), 'MESBR_REF_CAMP' => env('MESBR_REF_CAMP'), 'MESBR_ENDPOINT' => env('MESBR_ENDPOINT'), diff --git a/config/opbrcharcut.php b/config/opbrcharcut.php new file mode 100644 index 00000000..0b07009f --- /dev/null +++ b/config/opbrcharcut.php @@ -0,0 +1,17 @@ + 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 +]; diff --git a/database/migrations/2022_03_10_121307_create_opbrcharcut_codes_table.php b/database/migrations/2022_03_10_121307_create_opbrcharcut_codes_table.php new file mode 100644 index 00000000..5bdae1c2 --- /dev/null +++ b/database/migrations/2022_03_10_121307_create_opbrcharcut_codes_table.php @@ -0,0 +1,35 @@ +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'); + } +} diff --git a/database/migrations/2022_03_10_121410_create_opbrcharcut_codes_eans_table.php b/database/migrations/2022_03_10_121410_create_opbrcharcut_codes_eans_table.php new file mode 100644 index 00000000..152c06f6 --- /dev/null +++ b/database/migrations/2022_03_10_121410_create_opbrcharcut_codes_eans_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('code')->unique(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('opbrcharcut_codes_eans'); + } +} diff --git a/resources/assets/images/opbrcharcut/Charcut-1-imprim.png b/resources/assets/images/opbrcharcut/Charcut-1-imprim.png new file mode 100644 index 00000000..4bd59989 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Charcut-1-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Charcut-2-imprim.png b/resources/assets/images/opbrcharcut/Charcut-2-imprim.png new file mode 100644 index 00000000..a5c8224d Binary files /dev/null and b/resources/assets/images/opbrcharcut/Charcut-2-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Charcut-3-imprim.png b/resources/assets/images/opbrcharcut/Charcut-3-imprim.png new file mode 100644 index 00000000..617a1398 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Charcut-3-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Mobile-Charcut-1-imprim.png b/resources/assets/images/opbrcharcut/Mobile-Charcut-1-imprim.png new file mode 100644 index 00000000..37767aa4 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Mobile-Charcut-1-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Mobile-Charcut-2-imprim.png b/resources/assets/images/opbrcharcut/Mobile-Charcut-2-imprim.png new file mode 100644 index 00000000..cf9f383c Binary files /dev/null and b/resources/assets/images/opbrcharcut/Mobile-Charcut-2-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Mobile-Charcut-3-imprim.png b/resources/assets/images/opbrcharcut/Mobile-Charcut-3-imprim.png new file mode 100644 index 00000000..0a914d5b Binary files /dev/null and b/resources/assets/images/opbrcharcut/Mobile-Charcut-3-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Mobile-Pane-1-imprim.png b/resources/assets/images/opbrcharcut/Mobile-Pane-1-imprim.png new file mode 100644 index 00000000..9e279301 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Mobile-Pane-1-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Mobile-Pane-2-imprim.png b/resources/assets/images/opbrcharcut/Mobile-Pane-2-imprim.png new file mode 100644 index 00000000..d8354581 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Mobile-Pane-2-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Mobile-Pane-3-imprim.png b/resources/assets/images/opbrcharcut/Mobile-Pane-3-imprim.png new file mode 100644 index 00000000..db47ad14 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Mobile-Pane-3-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Panne-1-imprim.png b/resources/assets/images/opbrcharcut/Panne-1-imprim.png new file mode 100644 index 00000000..cdaf5fd0 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Panne-1-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Panne-2-imprim.png b/resources/assets/images/opbrcharcut/Panne-2-imprim.png new file mode 100644 index 00000000..c2b77262 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Panne-2-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/Panne-3-imprim.png b/resources/assets/images/opbrcharcut/Panne-3-imprim.png new file mode 100644 index 00000000..3709c078 Binary files /dev/null and b/resources/assets/images/opbrcharcut/Panne-3-imprim.png differ diff --git a/resources/assets/images/opbrcharcut/img-BR.png b/resources/assets/images/opbrcharcut/img-BR.png new file mode 100644 index 00000000..a3467026 Binary files /dev/null and b/resources/assets/images/opbrcharcut/img-BR.png differ diff --git a/resources/assets/images/opbrcharcut/img_br_01.png b/resources/assets/images/opbrcharcut/img_br_01.png new file mode 100644 index 00000000..5cb2a5c0 Binary files /dev/null and b/resources/assets/images/opbrcharcut/img_br_01.png differ diff --git a/resources/assets/images/opbrcharcut/img_br_02.png b/resources/assets/images/opbrcharcut/img_br_02.png new file mode 100644 index 00000000..bb3f0ef9 Binary files /dev/null and b/resources/assets/images/opbrcharcut/img_br_02.png differ diff --git a/resources/assets/images/opbrcharcut/img_br_03.png b/resources/assets/images/opbrcharcut/img_br_03.png new file mode 100644 index 00000000..56cbe5b5 Binary files /dev/null and b/resources/assets/images/opbrcharcut/img_br_03.png differ diff --git a/resources/assets/images/opbrcharcut/opbr_banner.jpg b/resources/assets/images/opbrcharcut/opbr_banner.jpg new file mode 100644 index 00000000..09da279e Binary files /dev/null and b/resources/assets/images/opbrcharcut/opbr_banner.jpg differ diff --git a/resources/assets/images/opbrcharcut/opbr_banner_mobile.png b/resources/assets/images/opbrcharcut/opbr_banner_mobile.png new file mode 100644 index 00000000..6afe6b7e Binary files /dev/null and b/resources/assets/images/opbrcharcut/opbr_banner_mobile.png differ diff --git a/resources/assets/images/opbrcharcut/print_banner.jpg b/resources/assets/images/opbrcharcut/print_banner.jpg new file mode 100644 index 00000000..a6345d04 Binary files /dev/null and b/resources/assets/images/opbrcharcut/print_banner.jpg differ diff --git a/resources/sass/_variables.scss b/resources/sass/_variables.scss index 8d67fdfb..861e722b 100644 --- a/resources/sass/_variables.scss +++ b/resources/sass/_variables.scss @@ -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; diff --git a/resources/sass/front/_sub_header.scss b/resources/sass/front/_sub_header.scss index 8faa811a..cc997f01 100644 --- a/resources/sass/front/_sub_header.scss +++ b/resources/sass/front/_sub_header.scss @@ -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; diff --git a/resources/sass/front/pages/club/_reductions.scss b/resources/sass/front/pages/club/_reductions.scss index 95191643..c5f7112c 100644 --- a/resources/sass/front/pages/club/_reductions.scss +++ b/resources/sass/front/pages/club/_reductions.scss @@ -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; } } } diff --git a/resources/sass/front/pages/opbrcharcut/_enter-code.scss b/resources/sass/front/pages/opbrcharcut/_enter-code.scss new file mode 100644 index 00000000..056fbe0a --- /dev/null +++ b/resources/sass/front/pages/opbrcharcut/_enter-code.scss @@ -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; + } + } +} diff --git a/resources/sass/front/pages/opbrcharcut/_reductions.scss b/resources/sass/front/pages/opbrcharcut/_reductions.scss new file mode 100644 index 00000000..8b0e5875 --- /dev/null +++ b/resources/sass/front/pages/opbrcharcut/_reductions.scss @@ -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; + } + } + } +} diff --git a/resources/sass/front/pages/opbrcharcut/_subheader.scss b/resources/sass/front/pages/opbrcharcut/_subheader.scss new file mode 100644 index 00000000..59431828 --- /dev/null +++ b/resources/sass/front/pages/opbrcharcut/_subheader.scss @@ -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"; + } + } +} \ No newline at end of file diff --git a/resources/sass/front/pages/opbrcharcut/_variables.scss b/resources/sass/front/pages/opbrcharcut/_variables.scss new file mode 100644 index 00000000..3efa00fc --- /dev/null +++ b/resources/sass/front/pages/opbrcharcut/_variables.scss @@ -0,0 +1,6 @@ +// OP BR +$opbrImgColor: #f9fafa; +$opbrFormColor: #f3ebe4; +$opbrFormTitleColor: #fff200; +$opbrFormBgColor: #00acef; +$opbrUnderlign: #ffca00; \ No newline at end of file diff --git a/resources/sass/front/pages/opbrcharcut/all.scss b/resources/sass/front/pages/opbrcharcut/all.scss new file mode 100644 index 00000000..2c7a78c9 --- /dev/null +++ b/resources/sass/front/pages/opbrcharcut/all.scss @@ -0,0 +1,4 @@ +@import "variables"; +@import "subheader"; +@import "enter-code"; +@import "reductions"; \ No newline at end of file diff --git a/resources/sass/main.scss b/resources/sass/main.scss index 10cc4cbc..db3b3d40 100644 --- a/resources/sass/main.scss +++ b/resources/sass/main.scss @@ -88,3 +88,5 @@ @import "front/pages/onsengage/bloc3"; @import "front/pages/onsengage/bloc4"; @import "front/pages/onsengage/bloc5"; + +@import "front/pages/opbrcharcut/all"; diff --git a/resources/views/front/mails/notif-panier.blade.php b/resources/views/front/mails/notif-panier.blade.php new file mode 100644 index 00000000..36171bee --- /dev/null +++ b/resources/views/front/mails/notif-panier.blade.php @@ -0,0 +1,73 @@ + +
+ +|
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+ |
+
+
+
+ |
+ ||||
+ Profitez de vos bons d'achat+ |
+ ||||
|
+ Bonjour{{ $user->firstname !== null ? " " . $user->firstname : null }}, +Vous venez de créditer des bons d'achat sur votre compte le club des Gaulois! ++ Pour imprimez vos bons : |
+ ||||
|
+ Gauloisement vôtre, |
+ ||||
| + |
+
+
+
+ |
+
+
+
+
+ |
+ + | + |
Bonjour,
+{{ $msg }}
diff --git a/resources/views/front/opbrcharcut/enter-code.blade.php b/resources/views/front/opbrcharcut/enter-code.blade.php new file mode 100644 index 00000000..a5fa1310 --- /dev/null +++ b/resources/views/front/opbrcharcut/enter-code.blade.php @@ -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') + +@endsection + +@section('content') +
+ Pour télécharger vos webcoupons, veuillez renseigner les champs suivants :
+ +Pour profiter des bons de réduction, merci de vous connecter à votre compte Le Gaulois.
+ Connexion + @endauth + @if ($errors->any()) +• {{ $error }}
+ @endforeach +
+
+
+
+
+
+
+
+
+
+
+
+