fix: show article name and admin link in stock alert email

Fix ``AlerteStock`` to use ``name`` instead of non-existent ``title``
field on articles, so the article name actually appears in the email.
Add ``lien_article`` variable with a direct link to the admin article
edit page. Update the DB template with a button and text link.
This commit is contained in:
Valentin Lab
2026-02-20 12:08:57 +01:00
parent 94af725373
commit ef52addc7d
2 changed files with 132 additions and 1 deletions

View File

@@ -23,14 +23,20 @@ class AlerteStock extends TemplateMailable
public $seuil;
public $lien_article;
public $lien_offre;
protected static $templateModelClass = MailTemplate::class;
public function __construct($offer)
{
$this->article = $offer->article->title ?? 'Article #'.$offer->article_id;
$this->article = $offer->article->name ?? 'Article #'.$offer->article_id;
$this->offre = $offer->id;
$this->stock_restant = $offer->stock_current;
$this->seuil = $offer->minimum_ondemand;
$this->lien_article = url('/Admin/Shop/Articles/edit/'.$offer->article_id);
$this->lien_offre = url('/Admin/Shop/Offers/edit/'.$offer->id);
}
public function envelope()

View File

@@ -0,0 +1,125 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
DB::table('mail_templates')
->where('mailable', 'App\\Mail\\AlerteStock')
->update([
'html_template' => json_encode(['fr' => $this->getHtmlTemplate()], JSON_UNESCAPED_UNICODE),
'text_template' => json_encode(['fr' => $this->getTextTemplate()], JSON_UNESCAPED_UNICODE),
'updated_at' => now(),
]);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
DB::table('mail_templates')
->where('mailable', 'App\\Mail\\AlerteStock')
->update([
'html_template' => json_encode(['fr' => $this->getOldHtmlTemplate()], JSON_UNESCAPED_UNICODE),
'text_template' => json_encode(['fr' => $this->getOldTextTemplate()], JSON_UNESCAPED_UNICODE),
'updated_at' => now(),
]);
}
private function getHtmlTemplate(): string
{
return '<table style="min-width: 100%;" width="100%" cellspacing="0" cellpadding="0">'
.'<tbody><tr><td>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr>'
.'<td style="margin: 0px auto; padding: 32px 0px 24px 4px; vertical-align: top;" align="center">'
.'<a href="https://www.jardinenvie.com/" style="text-decoration: none; color: #000000;">'
.'<img alt="Jardin\'enVie" src="https://boutique.jardinenvie.com/img/logo.png" style="margin: 0px auto; display: block;" width="300" height="138" border="0" /></a></td>'
.'</tr></tbody></table>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr><td style="margin: 0 auto; padding: 0px; vertical-align: top;">'
.'<table style="border-collapse: collapse; margin: 0 auto; width: 512px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody>'
.'<tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; line-height: 40px; color: #000000; font-size: 28px; padding: 20px 0px 10px 0px; font-weight: 800; text-align: center;">'
.'Alerte stock bas</td></tr>'
.'<tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; line-height: 28px; color: #000000; font-size: 16px; text-align: center; padding: 10px 0 30px 0;">'
.'<p>Le stock de l\'article <strong>{{article}}</strong> (offre n&deg;{{offre}}) '
.'a atteint le seuil d\'alerte.</p>'
.'<p style="font-size: 24px; font-weight: bold; color: #c0392b; padding: 10px 0;">{{stock_restant}} unit&eacute;s restantes</p>'
.'<p>Seuil d\'alerte configur&eacute; : {{seuil}} unit&eacute;s</p>'
.'<p style="padding-top: 15px;"><a href="{{lien_article}}" style="display: inline-block; padding: 10px 20px; background-color: #3498db; color: #ffffff; text-decoration: none; border-radius: 4px; font-weight: bold;">Voir l\'article</a>'
.'&nbsp;&nbsp;<a href="{{lien_offre}}" style="display: inline-block; padding: 10px 20px; background-color: #27ae60; color: #ffffff; text-decoration: none; border-radius: 4px; font-weight: bold;">Voir l\'offre</a></p>'
.'<p style="padding-top: 10px; color: #666;">Pensez &agrave; r&eacute;approvisionner cet article.</p>'
.'</td></tr>'
.'</tbody></table>'
.'</td></tr></tbody></table>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px; text-align: center;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; font-size: 12px; font-weight: 600; line-height: 20px; padding: 16px; color: #999999;">'
.'Jardin\'enVie Artisan Semencier<br />429 route des chaux, 26500 Bourg les Valence - Dr&ocirc;me'
.'</td></tr></tbody></table>'
.'</td></tr></tbody></table>';
}
private function getTextTemplate(): string
{
return "ALERTE STOCK BAS\n\n"
."Article : {{article}} (offre n°{{offre}})\n"
."Stock restant : {{stock_restant}} unités\n"
."Seuil d'alerte : {{seuil}} unités\n\n"
."Voir l'article dans l'admin : {{lien_article}}\n"
."Voir l'offre dans l'admin : {{lien_offre}}\n\n"
."Pensez à réapprovisionner cet article.\n\n"
."Jardin'enVie Artisan Semencier\n"
.'429 route des chaux, 26500 Bourg les Valence - Drôme';
}
private function getOldHtmlTemplate(): string
{
return '<table style="min-width: 100%;" width="100%" cellspacing="0" cellpadding="0">'
.'<tbody><tr><td>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr>'
.'<td style="margin: 0px auto; padding: 32px 0px 24px 4px; vertical-align: top;" align="center">'
.'<a href="https://www.jardinenvie.com/" style="text-decoration: none; color: #000000;">'
.'<img alt="Jardin\'enVie" src="https://boutique.jardinenvie.com/img/logo.png" style="margin: 0px auto; display: block;" width="300" height="138" border="0" /></a></td>'
.'</tr></tbody></table>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr><td style="margin: 0 auto; padding: 0px; vertical-align: top;">'
.'<table style="border-collapse: collapse; margin: 0 auto; width: 512px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody>'
.'<tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; line-height: 40px; color: #000000; font-size: 28px; padding: 20px 0px 10px 0px; font-weight: 800; text-align: center;">'
.'Alerte stock bas</td></tr>'
.'<tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; line-height: 28px; color: #000000; font-size: 16px; text-align: center; padding: 10px 0 30px 0;">'
.'<p>Le stock de l\'article <strong>{{article}}</strong> (offre n&deg;{{offre}}) '
.'a atteint le seuil d\'alerte.</p>'
.'<p style="font-size: 24px; font-weight: bold; color: #c0392b; padding: 10px 0;">{{stock_restant}} unit&eacute;s restantes</p>'
.'<p>Seuil d\'alerte configur&eacute; : {{seuil}} unit&eacute;s</p>'
.'<p style="padding-top: 15px; color: #666;">Pensez &agrave; r&eacute;approvisionner cet article.</p>'
.'</td></tr>'
.'</tbody></table>'
.'</td></tr></tbody></table>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px; text-align: center;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; font-size: 12px; font-weight: 600; line-height: 20px; padding: 16px; color: #999999;">'
.'Jardin\'enVie Artisan Semencier<br />429 route des chaux, 26500 Bourg les Valence - Dr&ocirc;me'
.'</td></tr></tbody></table>'
.'</td></tr></tbody></table>';
}
private function getOldTextTemplate(): string
{
return "ALERTE STOCK BAS\n\n"
."Article : {{article}} (offre n°{{offre}})\n"
."Stock restant : {{stock_restant}} unités\n"
."Seuil d'alerte : {{seuil}} unités\n\n"
."Pensez à réapprovisionner cet article.\n\n"
."Jardin'enVie Artisan Semencier\n"
.'429 route des chaux, 26500 Bourg les Valence - Drôme';
}
};