feat: Somes f***in changes, vivement qu'on sorte le legacy

This commit is contained in:
Vincent BRIDIER 2025-11-05 21:09:05 +01:00 • committed by Noah Lancien
parent db2da3543d
commit 94a4e04b50
21 changed files with 554 additions and 394 deletions

View file

@ -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

View file

@ -0,0 +1,89 @@
<?php
namespace App\Console\Commands;
use App\Contact;
use Carbon\Carbon;
use Illuminate\Console\Command;
class CustomersClaims extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'customers:claims';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$siteId = 'LGL89';
$claims = [
'natacha.larche@orange.fr' => '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;
}
}

View file

@ -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');
}
}

View file

@ -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;

View file

@ -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 {
/**

View file

@ -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'))))]);
}
}

View file

@ -0,0 +1,85 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Calendrier;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\Basket\PrintRequest;
use App\Models\Basket;
use App\Traits\GenerateBR;
use PDF;
use Illuminate\Http\Request;
use LDC\LDCCRM\CrmApiV2;
class BasketController extends Controller
{
use GenerateBR;
// FIXME: Docblock
public function show(Request $request, Basket $basket)
{
$totalQuantity = $basket->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')));
}
}

View file

@ -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]);
}

View file

@ -1,52 +0,0 @@
<?php
namespace App\Http\Requests\Customers;
use App\Http\Resources\StatusResource;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Contracts\Validation\Validator;
class PrintBasketRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'refcamp' => '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));
}
}
}

View file

@ -0,0 +1,49 @@
<?php
namespace App\Http\Requests\Fo\Basket;
use App\Enums\CampaignTypes;
use Illuminate\Foundation\Http\FormRequest;
class PrintRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
// FIXME: Docblock
protected function prepareForValidation()
{
$campagne = $this->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 [];
}
}

View file

@ -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('<nl>', $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()
{
}
}

View file

@ -1,5 +0,0 @@
<?php
return [
'endpoint' => env('CRM_ENDPOINT')
];

View file

@ -36,4 +36,8 @@ return [
'secret' => env('STRIPE_SECRET'),
],
'crm' => [
'endpoint' => env('CRM_ENDPOINT')
]
];

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AlterRefColumnOnBasketTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('baskets', function (Blueprint $table){
$table->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');
});
}
}

View file

@ -35,8 +35,5 @@
"sweetalert": "^2.0.8",
"vue": "^2.5.7",
"webpack-cli": "^6.0.1"
},
"dependencies": {
"node-sass": "^6.0.1"
}
}

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
<head>
<meta charset="UTF-8">
<title>{{ $basket->campagne->site->site_libelle }} - {{ __('Bons de Réduction') }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap 5 CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5 col-6">
<div class="text-center mb-4">
<img src="{{ asset($basket->campagne->site->site_logo) }}" alt="{{ $basket->campagne->site->site_libelle }}" class="img-fluid" style="max-width: 340px;">
</div>
<div class="card shadow-sm mb-4">
<div class="card-body">
<h5 class="card-title">Nombre de coupons :</h5>
<p class="card-text fs-3 fw-bold text-primary">{{ $totalQuantity }}</p>
</div>
</div>
@if($totalQuantity)
<div class="mb-3">
<h4>Liste des coupons :</h4>
<ul class="list-group">
@foreach ($basket->contents as $content)
@php
$remain = $content->quantity - $content->printed;
@endphp
@if($remain)
<li class="list-group-item">
<strong>Nom :</strong> {{ $content->coupon->coupon_name }}<br>
<strong>Quantité :</strong> {{ $remain }}
</li>
@endif
@endforeach
</ul>
</div>
<div class="text-center">
<a class="btn btn-primary" href="{{ route('fo.basket.print', $basket) }}">{{ __('Récupérer') }}</a>
</div>
@endif
</div>
<!-- Bootstrap JS (optionnel) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View file

@ -13,10 +13,13 @@
<table width="100%" align="center" cellpadding="0" cellspacing="0" border="0">
<tr>
<td width="100%" align="center">
@php
$total = count($coupons);
@endphp
@foreach($coupons as $k => $coupon)
<img src="{{ $coupon }}" border="0" style="display:block;width:165mm;"/>
<br>
@if (($k + 1) % 3 === 0)
@if (($k + 1) % 3 === 0 && $total > 3)
<div class="page-break"></div>
@endif
@endforeach

View file

@ -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');

View file

@ -1,16 +0,0 @@
<?php
/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int)$user->id === (int)$id;
});

View file

@ -1,18 +0,0 @@
<?php
use Illuminate\Foundation\Inspiring;
/*
|--------------------------------------------------------------------------
| Console Routes
|--------------------------------------------------------------------------
|
| This file is where you may define all of your Closure based console
| commands. Each Closure is bound to a command instance allowing a
| simple approach to interacting with each command's IO methods.
|
*/
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->describe('Display an inspiring quote');

View file

@ -1,5 +1,6 @@
<?php
use App\Http\Controllers\Fo\BasketController;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
@ -82,3 +83,14 @@ Route::any('/imprimer', 'MurController@printMur');
Route::any('/merci', 'MurController@getThanks');
Route::any('/index', 'AjaxController@backToIndex');
Route::any('/', "RedirectController");
/**
* Clean
*/
Route::name('fo.')->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');
});
});