From 94a4e04b5045a26f586bfb5adf62702c89bfd065 Mon Sep 17 00:00:00 2001 From: Vincent BRIDIER Date: Wed, 5 Nov 2025 21:09:05 +0100 Subject: [PATCH] feat: Somes f***in changes, vivement qu'on sorte le legacy --- .env.example | 6 +- app/Console/Commands/CustomersClaims.php | 89 +++++++ app/Console/Kernel.php | 16 +- .../Controllers/Api/v1/BasketController.php | 170 +++++++------ .../Controllers/Api/v1/CouponsController.php | 2 +- .../Controllers/Api/v1/CustomerController.php | 72 +----- app/Http/Controllers/Fo/BasketController.php | 85 +++++++ .../Controllers/StatistiqueController.php | 33 +-- .../Requests/Customers/PrintBasketRequest.php | 52 ---- app/Http/Requests/Fo/Basket/PrintRequest.php | 49 ++++ app/Traits/GenerateBR.php | 227 +++++++++--------- config/crm.php | 5 - config/services.php | 4 + ...03126_alter_ref_column_on_basket_table.php | 34 +++ package.json | 3 - resources/views/fo/basket/show.blade.php | 49 ++++ resources/views/pdf/coupons.blade.php | 5 +- routes/api.php | 1 - routes/channels.php | 16 -- routes/console.php | 18 -- routes/web.php | 12 + 21 files changed, 554 insertions(+), 394 deletions(-) create mode 100644 app/Console/Commands/CustomersClaims.php create mode 100644 app/Http/Controllers/Fo/BasketController.php delete mode 100644 app/Http/Requests/Customers/PrintBasketRequest.php create mode 100644 app/Http/Requests/Fo/Basket/PrintRequest.php delete mode 100644 config/crm.php create mode 100644 database/migrations/2025_10_30_103126_alter_ref_column_on_basket_table.php create mode 100644 resources/views/fo/basket/show.blade.php delete mode 100644 routes/channels.php delete mode 100644 routes/console.php diff --git a/.env.example b/.env.example index 61908c1..f86eaea 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ APP_URL=http://localhost LOG_CHANNEL=stack DB_CONNECTION=mysql -DB_HOST=127.0.0.1 +DB_HOST=dev-mysql DB_PORT=3306 DB_DATABASE=homestead DB_USERNAME=homestead @@ -20,8 +20,8 @@ SESSION_DRIVER=file SESSION_LIFETIME=120 MAIL_DRIVER=smtp -MAIL_HOST=smtp.mailtrap.io -MAIL_PORT=2525 +MAIL_HOST=dev-mailpit +MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null diff --git a/app/Console/Commands/CustomersClaims.php b/app/Console/Commands/CustomersClaims.php new file mode 100644 index 0000000..dbf4fb9 --- /dev/null +++ b/app/Console/Commands/CustomersClaims.php @@ -0,0 +1,89 @@ + '01/10/2025', + 'delphine.byon@hotmail.fr' => '30/09/2025', + 'aurel_del@hotmail.fr' => '27/09/2025', + 'katy.lancelot@orange.fr' => '26/09/2025' + ]; + + $emails = array_keys($claims); + + // On récupère les contact dont l'identifiant est un ID de CRM + $contacts = Contact::whereIn('contact_email', $emails) + ->where('contact_siteId', '=', $siteId) + ->get(); + + $toAdd = []; + + // Pour chaque contact + foreach ($contacts as $contact) { + + $claimDate = Carbon::createFromFormat('d/m/Y', $claims[$contact->contact_email])->format('Y-m-d'); + + // On vient chercher les paniers dont la date de création est >= à la date de la récla + $paniers = $contact->paniers()->where('panier_createdate', '>=', $claimDate)->get(); + + foreach ($paniers as $panier) { + foreach ($panier->panierContents as $content) { + $contactEmail = $contact->contact_email; + $campId = $panier->panier_campId; + $couponId = $content->panier_content_couponId; + + if (!isset($toAdd[$contactEmail][$campId])) { + $toAdd[$contactEmail][$campId] = []; + } + if (!isset($toAdd[$contactEmail][$campId][$couponId])) { + $toAdd[$contactEmail][$campId][$couponId] = 0; + } + + $toAdd[$contactEmail][$campId][$couponId] += $content->panier_content_printed; + } + } + } + + dd($toAdd); + + return 0; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index ef94244..206dd09 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -23,7 +23,9 @@ class Kernel extends ConsoleKernel * * @var array */ - protected $commands = []; + protected $commands = [ + \App\Console\Commands\CustomersClaims::class, + ]; /** * Define the application's command schedule. @@ -104,16 +106,4 @@ class Kernel extends ConsoleKernel } })->weekdays()->at('7:00'); } - - /** - * Register the commands for the application. - * - * @return void - */ - protected function commands() - { - $this->load(__DIR__ . '/Commands'); - - require base_path('routes/console.php'); - } } diff --git a/app/Http/Controllers/Api/v1/BasketController.php b/app/Http/Controllers/Api/v1/BasketController.php index 92a2006..c7c0da0 100644 --- a/app/Http/Controllers/Api/v1/BasketController.php +++ b/app/Http/Controllers/Api/v1/BasketController.php @@ -17,9 +17,7 @@ use App\Traits\LogTrait; class BasketController extends Controller { - use ThanksTrait; - use CouponTrait; - use LogTrait; + use ThanksTrait, CouponTrait, LogTrait; protected $logSource; protected $logAction; @@ -27,157 +25,157 @@ class BasketController extends Controller public function __construct() { $this->logAction = LogActions::updatebasket(); + $this->logSource = 'API'; } public function updateBasket(Request $request) { - $this->logSource = isset($request->admin) ? 'ADMIN' : 'API'; - - // ---- Contrôle des paramètres + // Validate required parameters + $requiredParams = ['customer_hashcode', 'refcamp', 'refsite', 'panier']; $error = false; - if ( - (!isset($request->customer_hashcode) || $request->customer_hashcode == "") || - (!isset($request->refcamp) || $request->refcamp == "") || - (!isset($request->refsite) || $request->refsite == "") || - (!isset($request->panier) || $request->panier == "") - ) { - $error = true; + foreach ($requiredParams as $param) { + if (empty($request->{$param})) { + $error = true; + break; + } } - - $refcamp = $request->refcamp; - $campagne = Campagne::where(['camp_id' => $refcamp])->first(); - if (!$campagne || $campagne->camp_published == 0 || ($campagne->camp_type->value != 1 && $campagne->camp_type->value != 3)) { - $this->writeLogErrorIncorrectCampaign($refcamp); + if ($error) { + $this->writeLogErrorWrongRequestParameters( + $request->refcamp ?? null, + $request->customer_hashcode ?? null, + $request->refsite ?? null, + $request->panier ?? null + ); return response()->json([ - 'Statut' => 'KO', - 'Code' => 103, - 'Message' => 'La campagne n\'existe pas ou n\'est pas un panier' + 'Statut' => 'KO', + 'Code' => 101, + 'Message' => 'Des paramètres de la requête sont mal renseignés ou non présents' + ]); + } + + // Validate campaign + $refcamp = $request->refcamp; + $campagne = Campagne::where('camp_id', $refcamp)->first(); + + if (!$campagne || $campagne->camp_published == 0 || !in_array($campagne->camp_type->value, [1, 3])) { + $this->writeLogErrorIncorrectCampaign($refcamp); + return response()->json([ + 'Statut' => 'KO', + 'Code' => 103, + 'Message' => 'La campagne n\'existe pas ou n\'est pas un panier' ]); } $refsite = $request->refsite; if ($refsite != $campagne->camp_siteId) { return response()->json([ - 'Statut' => 'KO', - 'Code' => 103, - 'Message' => 'La campagne ne correspond à aucune campagnes du site' + 'Statut' => 'KO', + 'Code' => 103, + 'Message' => 'La campagne ne correspond à aucune campagnes du site' ]); } - $panier = $request->panier; - $panierTab = explode(",", $panier); - $coupons = array(); - foreach ($panierTab as $panier) { - $pos = strpos($panier, ")"); + // Parse panier + $panierTab = explode(",", $request->panier); + $coupons = []; + foreach ($panierTab as $item) { + $pos = strpos($item, ")"); if ($pos === false) { $error = true; + break; } - $quantity = substr($panier, 0, $pos); - $quantity = str_replace("(", "", $quantity); - $couponCode = substr($panier, $pos + 1); + + $quantity = str_replace("(", "", substr($item, 0, $pos)); + $couponCode = substr($item, $pos + 1); if (is_numeric($quantity) && is_numeric($couponCode) && $quantity > 0) { if (isset($coupons[$couponCode])) { - $coupons[$couponCode] = $coupons[$couponCode] + $quantity; + $coupons[$couponCode] += $quantity; } else { $coupons[$couponCode] = $quantity; } } } - if (count($coupons) == 0) { - die(); - } - // ---- Préparation message de log avec coupons - if (isset($coupons)) { - $panierCoupons = array(); - foreach ($coupons as $code => $qty) { - array_push($panierCoupons, ['cp_code' => $code, 'qty' => $qty]); - } + if (empty($coupons)) { + die(); } if ($error) { $this->writeLogErrorWrongRequestParameters( - $request->refcamp, + $refcamp, $request->customer_hashcode, $campagne->camp_siteId, $request->panier ); return response()->json([ - 'Statut' => 'KO', - 'Code' => 101, - 'Message' => 'Des paramètres de la requête sont mal renseignés ou non présents' + 'Statut' => 'KO', + 'Code' => 101, + 'Message' => 'Des paramètres de la requête sont mal renseignés ou non présents' ]); } - // ---- Récupération du Customer - $customer = Customers::where(['hashcode' => $request->customer_hashcode])->first(); + // Prepare panierCoupons for logging + $panierCoupons = []; + foreach ($coupons as $code => $qty) { + $panierCoupons[] = ['cp_code' => $code, 'qty' => $qty]; + } - // ---- Ajout/MAJ du panier - $panier = Basket::where(['campagne_id' => $refcamp, 'customer_id' => $customer->id])->first(); - if ($panier) { + // Retrieve customer + $customer = Customers::where('hashcode', $request->customer_hashcode)->first(); + + // Retrieve or create basket + $basket = Basket::where(['campagne_id' => $refcamp, 'customer_id' => $customer->id])->first(); + + if ($basket) { + $camp = Campagne::where('camp_id', $basket->campagne_id)->first(); foreach ($coupons as $couponCode => $quantity) { - $camp = Campagne::where('camp_id', $panier->campagne_id)->first(); - $cp = $camp->coupons()->where('coupon_code', $couponCode)->first(); + $cp = $camp->coupons()->where('coupon_code', $couponCode)->first(); if ($cp) { - $panierContent = BasketContent::where(['basket_id' => $panier->id, 'coupon_id' => $cp->coupon_id])->first(); - if ($panierContent) { - $panierContent->quantity = $quantity + $panierContent->quantity; - // MAJ du contenu - $panierContent->save(); + $basketContent = BasketContent::where(['basket_id' => $basket->id, 'coupon_id' => $cp->coupon_id])->first(); + if ($basketContent) { + $basketContent->quantity += $quantity; + $basketContent->save(); } else { - // Ajout du contenu - $this->addContentToBasket($panier, $cp, $quantity); + $this->addContentToBasket($basket, $cp, $quantity); } } - }//end foreach + } } else { - // Ajout du panier et du contenu - $panier = new Basket(); - $panier->ref = Str::uuid(); - $panier->campagne()->associate($refcamp); - $panier->customer()->associate($customer); - $panier->save(); + $basket = new Basket(); + $basket->ref = (string) Str::uuid(); + $basket->campagne()->associate($refcamp); + $basket->customer()->associate($customer); + $basket->save(); foreach ($coupons as $couponCode => $quantity) { $cp = $campagne->coupons()->where('coupon_code', $couponCode)->first(); if ($cp) { - // Ajout du contenu - $this->addContentToBasket($panier, $cp, $quantity); + $this->addContentToBasket($basket, $cp, $quantity); } } - }//end if + } + // Log success $this->writeLogSuccessBasketCreated( - $request->refcamp, + $refcamp, $request->customer_hashcode, - $request->refsite, + $refsite, $request->panier, $panierCoupons ); return response()->json([ 'Statut' => 'OK', - 'Panier' => $panier + 'Panier' => $basket ]); } - /** - * Add a content line for a given basket. - * - * @param Basket $basket Related basket. - * @param Coupon $coupon The coupon that will be added to the basket. - * @param integer $quantity The quantity of coupons. - * @return void - */ - private function addContentToBasket( - Basket $basket, - Coupon $coupon, - int $quantity - ): void { + private function addContentToBasket(Basket $basket, Coupon $coupon, int $quantity): void + { if ($quantity > 0) { $newBasketContent = new BasketContent(); $newBasketContent->basket_id = $basket->id; diff --git a/app/Http/Controllers/Api/v1/CouponsController.php b/app/Http/Controllers/Api/v1/CouponsController.php index 36e9cf1..7532d36 100644 --- a/app/Http/Controllers/Api/v1/CouponsController.php +++ b/app/Http/Controllers/Api/v1/CouponsController.php @@ -40,7 +40,7 @@ class CouponsController extends Controller return new StatusResource(['status' => 'KO', 'code' => 422, 'message' => 'Coupons not found.']); } - $crm = new CrmApiV2(config('crm.CRM_ENDPOINT'), $campagne->site->crm_token, $campagne->site->crm_password); + $crm = new CrmApiV2(config('services.crm.endpoint'), $campagne->site->crm_token, $campagne->site->crm_password); try { /** diff --git a/app/Http/Controllers/Api/v1/CustomerController.php b/app/Http/Controllers/Api/v1/CustomerController.php index 43015e5..4dcedaf 100644 --- a/app/Http/Controllers/Api/v1/CustomerController.php +++ b/app/Http/Controllers/Api/v1/CustomerController.php @@ -12,14 +12,11 @@ use App\Models\Customers; use App\Http\Controllers\Controller; use App\Http\Requests\Customers\BasketRequest; use App\Http\Requests\Customers\MurRequest; -use App\Http\Requests\Customers\PrintBasketRequest; use App\Http\Resources\CouponsResource; use App\Traits\CouponTrait; use App\Traits\GenerateBR; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Request; -use PDF; -use LDC\LDCCRM\CrmApiV2; class CustomerController extends Controller { @@ -240,7 +237,7 @@ class CustomerController extends Controller return new StatusResource([ 'status' => "OK", - 'ref' => $basket->ref, + 'ref' => $basket->uuid, 'name' => $campagne->camp_name, 'limited_printing' => $campagne->camp_limitedPrinting, 'available_coupon' => $nbCoupons, @@ -250,71 +247,4 @@ class CustomerController extends Controller 'coupons' => $coupons ]); } - - public function printBasket(PrintBasketRequest $request) - { - $datas = $request->validated(); - - $customer = Customers::where('hashcode', $datas['hashcode'])->first(); - $campagne = Campagne::find($datas['refcamp']); - - if (!$campagne->camp_type->equals(CampaignTypes::panier())) { - return new StatusResource(['status' => 'KO', 'code' => 404, 'message' => 'Campaign is not basket.']); - } - if ($campagne->camp_published === 0) { - return new StatusResource(['status' => 'KO', 'code' => 404, 'message' => 'Campaign not found.']); - } - if ($campagne->site->crm_token === null) { - return new StatusResource(['status' => 'KO', 'code' => 500, 'message' => 'CRM Token is missing for site_id : ' . $campagne->site->site_id]); - } - if ($campagne->site->crm_password === null) { - return new StatusResource(['status' => 'KO', 'code' => 500, 'message' => 'CRM Password is missing for site_id : ' . $campagne->site->site_id]); - } - $basket = $customer->baskets()->where('campagne_id', $campagne->camp_id)->first(); - if (is_null($basket)) { - return new StatusResource(['status' => 'KO', 'code' => 404, 'message' => 'Basket not found.']); - } - $crm = new CrmApiV2(config('crm.CRM_ENDPOINT'), $campagne->site->crm_token, $campagne->site->crm_password); - try { - /** - * @var \LDC\LDCCRM\Models\Customer - */ - $crmInfos = $crm->getCustomer($customer->hashcode); - } catch (\Exception $e) { - Log::critical($e->getMessage()); - return new StatusResource(['status' => 'KO', 'code' => 422, 'message' => 'Customer not found.']); - } - if (is_null($crmInfos)) { - return new StatusResource(['status' => 'KO', 'code' => 422, 'message' => 'Customer not found.']); - } - $coupons = []; - foreach ($basket->contents as $content) - { - $published = true; - $coupon = $content->coupon()->whereRaw("coupon_published = 1 AND (coupon_mindatediffusion IS NULL OR coupon_mindatediffusion <= NOW()) AND (coupon_maxdatediffusion IS NULL OR coupon_maxdatediffusion >= NOW()) AND (coupon_maxdatevalidity IS NULL OR coupon_maxdatevalidity >= NOW())")->first(); - if (!is_null($coupon)) - { - // ---- Contrôle des calendriers de diffusion - $calendars = Calendrier::where(['calendrier_couponId' => $coupon->coupon_id])->get(); - if (!$calendars->isEmpty()) { - $published = false; - foreach ($calendars as $calendar) { - if (strtotime(date('Y-m-d H:i:s')) > strtotime($calendar->calendrier_startdate) && strtotime(date('Y-m-d H:i:s')) < strtotime($calendar->calendrier_enddate)) { - $published = true; - } - } - } - if ($published){ - for ($i = 0; $i < ($content->quantity - $content->printed); $i++) { - $coupons[] = $this->printCoupon($coupon, $customer, $crmInfos, $campagne); - } - $content->printed = $content->quantity; - $content->save(); - } - } - } - - $pdf = PDF::loadView('pdf.coupons', ['coupons' => $coupons]); - return new StatusResource(['status' => 'OK', 'pdf' => base64_encode($pdf->stream(sprintf("coupons_%s_%s_%s.pdf", $crmInfos->firstname, $crmInfos->lastname, date('d-m-Y'))))]); - } } diff --git a/app/Http/Controllers/Fo/BasketController.php b/app/Http/Controllers/Fo/BasketController.php new file mode 100644 index 0000000..7669fce --- /dev/null +++ b/app/Http/Controllers/Fo/BasketController.php @@ -0,0 +1,85 @@ +contents->sum(function ($content) { + return $content->quantity - $content->printed; + }); + + return view('fo.basket.show', compact('basket', 'totalQuantity')); + } + + // FIXME: Docblock + public function print(PrintRequest $request, Basket $basket) + { + $campagne = $basket->campagne; + + // FIXME: Bump to CrmApiV4 + $crm = new CrmApiV2(config('services.crm.endpoint'), $campagne->site->crm_token, $campagne->site->crm_password); + + /** + * @var \LDC\LDCCRM\Models\Customer + */ + $crmInfos = $crm->getCustomer($basket->customer->hashcode); + + if (is_null($crmInfos)) { + throw new \Exception('Customer not found.'); + } + + $coupons = []; + $currentDateTime = date('Y-m-d H:i:s'); + + foreach ($basket->contents as $content) { + $coupon = $content->coupon()->whereRaw( + "coupon_published = 1 AND + (coupon_mindatediffusion IS NULL OR coupon_mindatediffusion <= NOW()) AND + (coupon_maxdatediffusion IS NULL OR coupon_maxdatediffusion >= NOW()) AND + (coupon_maxdatevalidity IS NULL OR coupon_maxdatevalidity >= NOW())" + )->first(); + + if ($coupon !== null) { + $calendars = Calendrier::where('calendrier_couponId', $coupon->coupon_id)->get(); + + $published = true; + if (!$calendars->isEmpty()) { + $published = false; + foreach ($calendars as $calendar) { + if ($currentDateTime > $calendar->calendrier_startdate && $currentDateTime < $calendar->calendrier_enddate) { + $published = true; + break; // Exit loop early as condition is met + } + } + } + + if ($published) { + $qtyToPrint = $content->quantity - $content->printed; + for ($i = 0; $i < $qtyToPrint; $i++) { + $coupons[] = $this->printCoupon($coupon, $basket->customer, $crmInfos, $campagne); + } + $content->printed = $content->quantity; + $content->save(); + } + } + } + + // $coupons contains all printed coupons + $pdf = PDF::loadView('pdf.coupons', ['coupons' => $coupons]); + return $pdf->download(sprintf("coupons_%s_%s_%s.pdf", $crmInfos->firstname, $crmInfos->lastname, date('d-m-Y'))); + } +} diff --git a/app/Http/Controllers/StatistiqueController.php b/app/Http/Controllers/StatistiqueController.php index a2e9f59..3227ff2 100644 --- a/app/Http/Controllers/StatistiqueController.php +++ b/app/Http/Controllers/StatistiqueController.php @@ -20,22 +20,23 @@ class StatistiqueController extends Controller */ public function index() { - $sites = Auth::user()->sites()->get(); - foreach ($sites as $site) { - if (isset($site->campagnes)) { - $campagnes = $site->campagnes; - foreach ($campagnes as $campagne) { - $coupons = $campagne->coupons; - foreach ($coupons as $coupon) { - $coupon->quantity = $this->getFullQuantity($coupon); - $coupon->remain = $this->getFullQuantity($coupon) - $this->getUsedQuantity($coupon); - $coupon->diffused = $this->getDiffusedQuantity($coupon); - $coupon->isPrintable = $this->isAvailableToPrint($coupon, $campagne); - $coupon->isPaused = $this->isPausedToPrint($coupon, $campagne); - } - }//end foreach - }//end if - }//end foreach + // $sites = Auth::user()->sites()->get(); + // foreach ($sites as $site) { + // if (isset($site->campagnes)) { + // $campagnes = $site->campagnes; + // foreach ($campagnes as $campagne) { + // $coupons = $campagne->coupons; + // foreach ($coupons as $coupon) { + // $coupon->quantity = $this->getFullQuantity($coupon); + // $coupon->remain = $this->getFullQuantity($coupon) - $this->getUsedQuantity($coupon); + // $coupon->diffused = $this->getDiffusedQuantity($coupon); + // $coupon->isPrintable = $this->isAvailableToPrint($coupon, $campagne); + // $coupon->isPaused = $this->isPausedToPrint($coupon, $campagne); + // } + // }//end foreach + // }//end if + // }//end foreach + $sites = []; return view('stats.index')->with(['sites' => $sites]); } diff --git a/app/Http/Requests/Customers/PrintBasketRequest.php b/app/Http/Requests/Customers/PrintBasketRequest.php deleted file mode 100644 index d9db769..0000000 --- a/app/Http/Requests/Customers/PrintBasketRequest.php +++ /dev/null @@ -1,52 +0,0 @@ - 'string|exists:campagne,camp_id|required', - 'hashcode' => 'string|exists:customers,hashcode|required' - ]; - } - - /** - * failedValidation - * @param Validator $validator - * @return void - * @throws BindingResolutionException - * @throws HttpResponseException - */ - protected function failedValidation(Validator $validator) - { - if ($this->wantsJson()) { - throw new HttpResponseException(response()->json(new StatusResource([ - 'status' => 'KO', - 'code' => 422, - 'message' => $validator->errors()->messages() - ]), 422)); - } - } -} diff --git a/app/Http/Requests/Fo/Basket/PrintRequest.php b/app/Http/Requests/Fo/Basket/PrintRequest.php new file mode 100644 index 0000000..1fb855a --- /dev/null +++ b/app/Http/Requests/Fo/Basket/PrintRequest.php @@ -0,0 +1,49 @@ +basket->campagne; + + if (!$campagne->camp_type->equals(CampaignTypes::panier())) { + throw new \Exception('Campaign is not basket.'); + } + + if ($campagne->camp_published === 0) { + throw new \Exception('Campaign is not published.'); + } + if ($campagne->site->crm_token === null) { + throw new \Exception('CRM Token is missing.'); + } + if ($campagne->site->crm_password === null) { + throw new \Exception('CRM Password is missing.'); + } + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return []; + } +} diff --git a/app/Traits/GenerateBR.php b/app/Traits/GenerateBR.php index d52aec2..20e5113 100644 --- a/app/Traits/GenerateBR.php +++ b/app/Traits/GenerateBR.php @@ -6,10 +6,8 @@ use App\Campagne; use App\Models\Customers; use Illuminate\Http\Request; use App\Coupon; -use App\Log; use App\Models\PrintedCoupons; use App\Site; -use Illuminate\Support\Facades\Log as FacadesLog; trait GenerateBR { @@ -42,7 +40,10 @@ trait GenerateBR $white = imagecolorallocate($ImageMentionFond, 255, 255, 255); imagefilledrectangle($ImageMentionFond, 0, 0, 414, 99, $white); $black = imagecolorallocate($ImageMentionFond, 0, 0, 0); - $lines_mentions = explode("\r\n", $txt_mentions); + + $cleanedString = str_replace(["\r", "\n"], '', $txt_mentions); + $lines_mentions = str_split($cleanedString, 92); + $y = 19; foreach ($lines_mentions as $line) { $this->imagettftextSp($ImageMentionFond, 7, 0, 15, $y, $black, $arial, $line, 0.01); @@ -147,7 +148,7 @@ trait GenerateBR } imagecolortransparent($ImageFond, $white); imagecopy($mask, $ImageFond, 360, 170, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); - }//end if + } //end if // ---- Copie le produit dans le mask $size = getimagesize($product_image); @@ -276,8 +277,8 @@ trait GenerateBR } // imagecolortransparent($ImageMentionFond, $white); imagecopy($mask, $ImageMentionFond, 335, 235, 0, 0, imagesx($ImageMentionFond), imagesy($ImageMentionFond)); - }//end if - }//end if + } //end if + } //end if // ---- Inscription de l'utilisateur et de la ville @@ -300,7 +301,7 @@ trait GenerateBR $dateValidite = date('d/m/Y', strtotime("+" . $coupon->coupon_validity . " day")); } else { $dateValidite = date('d/m/Y', strtotime("+30 day")); -// 30 jours par défaut + // 30 jours par défaut } $ImageFond = imagecreate(120, 40); @@ -361,7 +362,7 @@ trait GenerateBR $black = imagecolorallocate($ImageFond, 0, 0, 0); imagettftext($ImageFond, 11, 0, 0, 14, $black, $arial, $codeBarre); imagecopy($mask, $ImageFond, 52, 390, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); - }//end if + } //end if ob_start(); imagejpeg($mask, null, 100); @@ -378,57 +379,51 @@ trait GenerateBR // VB 22/04/2021 public function printCoupon(Coupon $coupon, Customers $customer, $crmInfos, Campagne $campagne) { - $arial = public_path() . '/build/assets/fonts/coupons/arial.ttf'; + $arial = public_path() . '/build/assets/fonts/coupons/arial.ttf'; $arialbd = public_path() . '/build/assets/fonts/coupons/arialbd.ttf'; - // ---- Masque dans lequel l'image finale sera placée - $mask = imagecreatefrompng($coupon->coupon_image); + // Load base mask image + $mask = imagecreatefrompng($coupon->coupon_image); list($maskWidth, $maskHeight) = getimagesize($coupon->coupon_image); - - // ----- Mentions légales + RCS dépendant de l'user + // --- Draw Legal Mentions + RCS depending on the user country if ($coupon->coupon_legal_mentions_splitted == 1) { $legalMentions = explode('', $coupon->coupon_legal_mentions); + if ($customer->country !== 250) { // BELGIQUE - Luxembourg - $txt_mentions = $legalMentions[0] . "\n\r" . $legalMentions[1] . " " . $coupon->coupon_rcs; - $ImageMentionFond = imagecreate(420, 145); - $boxMentions = imagettfbbox(7, 0, $arial, $txt_mentions); - $white = imagecolorallocate($ImageMentionFond, 255, 255, 255); - imagefilledrectangle($ImageMentionFond, 0, 0, 414, 99, $white); - $black = imagecolorallocate($ImageMentionFond, 0, 0, 0); - $lines_mentions = explode("\r\n", $txt_mentions); - $y = 19; - foreach ($lines_mentions as $line) { - $this->imagettftextSp($ImageMentionFond, 7, 0, 15, $y, $black, $arial, $line, 0.01); - $y = $y + 9; - } - // imagecolortransparent($ImageMentionFond, $white); - imagecopy($mask, $ImageMentionFond, 335, 235, 0, 0, imagesx($ImageMentionFond), imagesy($ImageMentionFond)); + $txt_mentions = $legalMentions[0] . "\n\r " . $legalMentions[1] . "\n\r " . $coupon->coupon_rcs; + $imageWidth = 420; + $imageHeight = 145; } else { - // FIXME : Semble non utilise ici // FR - $txt_mentions = $legalMentions[0] . " " . $coupon->coupon_rcs; - $ImageMentionFond = imagecreate(415, 100); - $boxMentions = imagettfbbox(7, 0, $arial, $txt_mentions); - $white = imagecolorallocate($ImageMentionFond, 255, 255, 255); - imagefilledrectangle($ImageMentionFond, 0, 0, 414, 99, $white); - $black = imagecolorallocate($ImageMentionFond, 0, 0, 0); - $lines_mentions = explode("\r\n", $txt_mentions); - $y = 19; - foreach ($lines_mentions as $line) { - $this->imagettftextSp($ImageMentionFond, 7, 0, 15, $y, $black, $arial, $line, 0.01); - $y = $y + 9; - } - // imagecolortransparent($ImageMentionFond, $white); - imagecopy($mask, $ImageMentionFond, 335, 235, 0, 0, imagesx($ImageMentionFond), imagesy($ImageMentionFond)); - }//end if - }//end if + $txt_mentions = $legalMentions[0] . " " . $coupon->coupon_rcs; + $imageWidth = 415; + $imageHeight = 100; + } + $ImageMentionFond = imagecreate($imageWidth, $imageHeight); + $white = imagecolorallocate($ImageMentionFond, 255, 255, 255); + imagefilledrectangle($ImageMentionFond, 0, 0, $imageWidth - 6, $imageHeight - 46, $white); + $black = imagecolorallocate($ImageMentionFond, 0, 0, 0); - // ---- Inscription de l'utilisateur et de la ville - $libelle = "OFFRE RÉSERVÉE À"; - $user = sprintf( + $cleanedString = str_replace(["\r", "\n"], '', $txt_mentions); + $lines_mentions = str_split($cleanedString, 92); + + $y = 19; + foreach ($lines_mentions as $line) { + $this->imagettftextSp($ImageMentionFond, 7, 0, 15, $y, $black, $arial, $line, 0.01); + $y += 9; + } + + imagecopy($mask, $ImageMentionFond, 335, 235, 0, 0, imagesx($ImageMentionFond), imagesy($ImageMentionFond)); + + imagedestroy($ImageMentionFond); + } + + // --- User inscription and city + $libelle = "OFFRE RÉSERVÉE À"; + $user = sprintf( "%s\r\n%s\r\n%s\r\n%s %s\r\n%s", $crmInfos->firstname, $crmInfos->lastname, @@ -437,124 +432,135 @@ trait GenerateBR $crmInfos->city, sprintf('id #%s', str_pad($customer->id, 13, "0", STR_PAD_LEFT)) ); - $ImageFond = imagecreate(120, 80); - $white = imagecolorallocate($ImageFond, 255, 255, 255); - $black = imagecolorallocate($ImageFond, 0, 0, 0); - $box2 = imagettfbbox(8, 0, $arial, $libelle); - imagettftext($ImageFond, 8, 0, (120 / 2) - (abs($box2[4]) - abs($box2[6])) / 2, 10, $black, $arialbd, $libelle); - // Write line by line. + $ImageFond = imagecreate(120, 80); + $white = imagecolorallocate($ImageFond, 255, 255, 255); + $black = imagecolorallocate($ImageFond, 0, 0, 0); + + // Centered libelle text + $boxLibelle = imagettfbbox(8, 0, $arial, $libelle); + $libelleX = (120 / 2) - (abs($boxLibelle[4]) - abs($boxLibelle[6])) / 2; + imagettftext($ImageFond, 8, 0, $libelleX, 10, $black, $arialbd, $libelle); + + // User lines $userLines = explode("\r\n", $user); - $y = 25; + $y = 25; foreach ($userLines as $line) { $box = imagettfbbox(8, 0, $arial, $line); - $this->imagettftextSp($ImageFond, 8, 0, (120 / 2) - (abs($box[4]) - abs($box[6])) / 2, $y, $black, $arial, $line, 0.01); - $y = $y + 10; + $lineX = (120 / 2) - (abs($box[4]) - abs($box[6])) / 2; + $this->imagettftextSp($ImageFond, 8, 0, $lineX, $y, $black, $arial, $line, 0.01); + $y += 10; } imagecolortransparent($ImageFond, $white); imagecopy($mask, $ImageFond, 770, 40, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); + imagedestroy($ImageFond); - // ---- Inscription de la date de validité + // --- Validity date inscription $libelle = "Valable jusqu'au :"; - - if ($coupon->coupon_validity != 0) { - $dateValidite = date('d/m/Y', strtotime("+" . $coupon->coupon_validity . " day")); - } else { - $dateValidite = date('d/m/Y', strtotime("+30 day")); - // 30 jours par défaut - } + $validDays = ($coupon->coupon_validity != 0) ? $coupon->coupon_validity : 30; + $dateValidite = date('d/m/Y', strtotime("+$validDays day")); $ImageFond = imagecreate(120, 40); - $white = imagecolorallocate($ImageFond, 255, 255, 255); - $black = imagecolorallocate($ImageFond, 0, 0, 0); + $white = imagecolorallocate($ImageFond, 255, 255, 255); + $black = imagecolorallocate($ImageFond, 0, 0, 0); + imagettftext($ImageFond, 8, 0, 1, 8, $black, $arialbd, $libelle); imagettftext($ImageFond, 8, 0, 20, 23, $black, $arial, $dateValidite); + imagecolortransparent($ImageFond, $white); imagecopy($mask, $ImageFond, 780, 142, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); + imagedestroy($ImageFond); - // Save printed coupon. + // Save printed coupon $printedCoupon = $this->savePrintedCoupon($campagne, $customer, $coupon); - // Right barcode + // --- Right barcode $codeBarre = str_pad($printedCoupon->id, 13, "0", STR_PAD_LEFT); $generator = new \Picqer\Barcode\BarcodeGeneratorPNG(); - $base64 = $generator->getBarcode($codeBarre, $generator::TYPE_CODE_128_A, 2, 46); + $base64 = $generator->getBarcode($codeBarre, $generator::TYPE_CODE_128, 2, 30); $barcodeImage = imagecreatefromstring($base64); - imagecopy($mask, $barcodeImage, 540, 342, 0, 0, imagesx($barcodeImage), imagesy($barcodeImage)); - // Text + + imagecopy($mask, $barcodeImage, 660, 355, 0, 0, imagesx($barcodeImage), imagesy($barcodeImage)); + imagedestroy($barcodeImage); + + // Text below right barcode $ImageFond = imagecreate(380, 15); $white = imagecolorallocate($ImageFond, 255, 255, 255); $black = imagecolorallocate($ImageFond, 0, 0, 0); imagettftext($ImageFond, 11, 0, 0, 14, $black, $arial, $codeBarre); - imagecopy($mask, $ImageFond, 795, 390, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); - // End text - // End right barcode + imagecopy($mask, $ImageFond, 800, 385, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); + imagedestroy($ImageFond); - // ---- Création code barre + // --- Barcode treatment text if ($customer->country !== 250) { $textReduc = "Traitement ScanCoupon/HighCo Data Benelux"; + $copyPosition = [70, 230]; } elseif ($coupon->coupon_treatment_center == 0) { $textReduc = "• Traitement ScanCoupon •"; + $copyPosition = [52, 322]; } else { $textReduc = "• Traitement Sogec •"; + $copyPosition = [52, 322]; } $ImageFond = imagecreate(270, 20); - $white = imagecolorallocate($ImageFond, 255, 255, 255); - $black = imagecolorallocate($ImageFond, 0, 0, 0); + $white = imagecolorallocate($ImageFond, 255, 255, 255); + $black = imagecolorallocate($ImageFond, 0, 0, 0); imagettftext($ImageFond, 9, 0, 0, 10, $black, $arialbd, $textReduc); - if ($customer->country !== 250) { - imagecopy($mask, $ImageFond, 70, 230, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); - } else { - imagecopy($mask, $ImageFond, 52, 322, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); - } + imagecopy($mask, $ImageFond, $copyPosition[0], $copyPosition[1], 0, 0, imagesx($ImageFond), imagesy($ImageFond)); + imagedestroy($ImageFond); - // Left barcode + // --- Left barcode if ($customer->country !== 250) { - $codeBarre = imagecreatefromjpeg($coupon->coupon_gs1code); - imageresolution($codeBarre, 72); + $codeBarreImg = imagecreatefromjpeg($coupon->coupon_gs1code); + imageresolution($codeBarreImg, 72); list($width, $height) = getimagesize($coupon->coupon_gs1code); - $r = $width / $height; - $w = 285; - $h = 150; - if ($w / $h > $r) { - $newwidth = $h * $r; - $newheight = $h; - } else { - $newheight = $w / $r; - $newwidth = $w; - } - $test = imagecreatetruecolor($newwidth, $newheight); - imagecopyresampled($test, $codeBarre, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); + $ratio = $width / $height; + $maxWidth = 285; + $maxHeight = 150; - imagecopy($mask, $test, 60, 250, 0, 0, imagesx($test), imagesy($test)); + if ($maxWidth / $maxHeight > $ratio) { + $newWidth = $maxHeight * $ratio; + $newHeight = $maxHeight; + } else { + $newHeight = $maxWidth / $ratio; + $newWidth = $maxWidth; + } + + $resizedImage = imagecreatetruecolor($newWidth, $newHeight); + imagecopyresampled($resizedImage, $codeBarreImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); + imagecopy($mask, $resizedImage, 60, 250, 0, 0, $newWidth, $newHeight); + imagedestroy($codeBarreImg); + imagedestroy($resizedImage); } else { - $codeBarre = $coupon->coupon_code; - $generator = new \Picqer\Barcode\BarcodeGeneratorPNG(); + $codeBarre = $coupon->coupon_code; + $generator = new \Picqer\Barcode\BarcodeGeneratorPNG(); $base64 = $generator->getBarcode($codeBarre, $generator::TYPE_CODE_128_A, 2, 46); $barcodeImage = imagecreatefromstring($base64); imagecopy($mask, $barcodeImage, 10, 342, 0, 0, imagesx($barcodeImage), imagesy($barcodeImage)); + imagedestroy($barcodeImage); + $ImageFond = imagecreate(380, 15); - $white = imagecolorallocate($ImageFond, 255, 255, 255); - $black = imagecolorallocate($ImageFond, 0, 0, 0); + $white = imagecolorallocate($ImageFond, 255, 255, 255); + $black = imagecolorallocate($ImageFond, 0, 0, 0); imagettftext($ImageFond, 11, 0, 0, 14, $black, $arial, $codeBarre); imagecopy($mask, $ImageFond, 52, 390, 0, 0, imagesx($ImageFond), imagesy($ImageFond)); - }//end if - // End left barcode + imagedestroy($ImageFond); + } + // Final output as base64 encoded JPEG ob_start(); imagejpeg($mask, null, 100); $contents = ob_get_contents(); ob_end_clean(); - $dataUri = "data:image/jpeg;base64," . base64_encode($contents); - // ---- Libère la mémoire associée aux images manipulées imagedestroy($mask); - imagedestroy($ImageFond); - return $dataUri; + + return "data:image/jpeg;base64," . base64_encode($contents); } + public function savePrintedCoupon(Campagne $campagne, Customers $customer, Coupon $coupon): PrintedCoupons { // ----- mémorise l'impression @@ -566,4 +572,9 @@ trait GenerateBR return $mur; } + + private function addMarketingDirectCode() + { + + } } diff --git a/config/crm.php b/config/crm.php deleted file mode 100644 index 4cc5fa5..0000000 --- a/config/crm.php +++ /dev/null @@ -1,5 +0,0 @@ - env('CRM_ENDPOINT') -]; diff --git a/config/services.php b/config/services.php index 0751cb1..aee46cf 100644 --- a/config/services.php +++ b/config/services.php @@ -36,4 +36,8 @@ return [ 'secret' => env('STRIPE_SECRET'), ], + 'crm' => [ + 'endpoint' => env('CRM_ENDPOINT') + ] + ]; diff --git a/database/migrations/2025_10_30_103126_alter_ref_column_on_basket_table.php b/database/migrations/2025_10_30_103126_alter_ref_column_on_basket_table.php new file mode 100644 index 0000000..1ac970d --- /dev/null +++ b/database/migrations/2025_10_30_103126_alter_ref_column_on_basket_table.php @@ -0,0 +1,34 @@ +renameColumn('ref', 'uuid'); + $table->unique('uuid'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('baskets', function (Blueprint $table){ + $table->dropUnique(['uuid']); + $table->renameColumn('uuid', 'ref'); + }); + } +} diff --git a/package.json b/package.json index 305947a..8444e3b 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,5 @@ "sweetalert": "^2.0.8", "vue": "^2.5.7", "webpack-cli": "^6.0.1" - }, - "dependencies": { - "node-sass": "^6.0.1" } } diff --git a/resources/views/fo/basket/show.blade.php b/resources/views/fo/basket/show.blade.php new file mode 100644 index 0000000..d83cdc0 --- /dev/null +++ b/resources/views/fo/basket/show.blade.php @@ -0,0 +1,49 @@ + + + + + {{ $basket->campagne->site->site_libelle }} - {{ __('Bons de Réduction') }} + + + + + +
+
+ {{ $basket->campagne->site->site_libelle }} +
+ +
+
+
Nombre de coupons :
+

{{ $totalQuantity }}

+
+
+ @if($totalQuantity) +
+

Liste des coupons :

+
    + @foreach ($basket->contents as $content) + @php + $remain = $content->quantity - $content->printed; + @endphp + @if($remain) +
  • + Nom : {{ $content->coupon->coupon_name }}
    + Quantité : {{ $remain }} +
  • + @endif + @endforeach +
+
+ + + @endif + +
+ + + + diff --git a/resources/views/pdf/coupons.blade.php b/resources/views/pdf/coupons.blade.php index 5888197..5bad066 100644 --- a/resources/views/pdf/coupons.blade.php +++ b/resources/views/pdf/coupons.blade.php @@ -13,10 +13,13 @@
+ @php + $total = count($coupons); + @endphp @foreach($coupons as $k => $coupon)
- @if (($k + 1) % 3 === 0) + @if (($k + 1) % 3 === 0 && $total > 3)
@endif @endforeach diff --git a/routes/api.php b/routes/api.php index 0c69088..4dfa3da 100644 --- a/routes/api.php +++ b/routes/api.php @@ -15,7 +15,6 @@ Route::prefix('v1') ->group(function () { Route::get('/customer/mur', 'Api\v1\CustomerController@mur'); Route::get('/customer/basket', 'Api\v1\CustomerController@basket'); - Route::get('/customer/basket/print', 'Api\v1\CustomerController@printBasket'); Route::get('/customer/basket/update', 'Api\v1\BasketController@updateBasket'); Route::resource('customer', 'Api\v1\CustomerController'); Route::get('/mur', 'Api\v1\MurController@show'); diff --git a/routes/channels.php b/routes/channels.php deleted file mode 100644 index 1e36a53..0000000 --- a/routes/channels.php +++ /dev/null @@ -1,16 +0,0 @@ -id === (int)$id; -}); diff --git a/routes/console.php b/routes/console.php deleted file mode 100644 index 23c267d..0000000 --- a/routes/console.php +++ /dev/null @@ -1,18 +0,0 @@ -comment(Inspiring::quote()); -})->describe('Display an inspiring quote'); diff --git a/routes/web.php b/routes/web.php index b71c6fa..a6099fd 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,6 @@ group(function() { + Route::name('basket.')->prefix('basket')->group(function () { + Route::get('/{basket:uuid}', [BasketController::class, 'show'])->name('show'); + Route::get('/{basket:uuid}/print', [BasketController::class, 'print'])->name('print'); + }); +});