new: send stock alert email when offer stock crosses threshold

When a purchase causes an offer's ``stock_current`` to drop to or below
its ``minimum_ondemand`` threshold, an email is sent to
``commande@jardinenvie.com`` using an editable mail template (Spatie
``MailTemplate``).

The check runs in ``OfferStocks::decreaseStock()`` after updating stock.
Only threshold-crossing events trigger the alert (not every low-stock
sale).  Failures are caught and logged to avoid disrupting the order
flow.
This commit is contained in:
Valentin Lab
2026-02-13 07:13:56 +01:00
parent cbd8e33f3b
commit 936c9473a7
3 changed files with 162 additions and 1 deletions

View File

@@ -2,19 +2,62 @@
namespace App\Repositories\Shop;
use App\Mail\AlerteStock;
use App\Models\Shop\Offer;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class OfferStocks
{
public static function decreaseStock($item)
{
$offer = Offers::get($item['offer_id']);
$previousStock = $offer->stock_current;
$offer->stock_current = $offer->stock_current - $item['quantity'];
if ($offer->stock_current <= 0) {
$offer->stock_current = 0;
}
return $offer->save();
$saved = $offer->save();
if ($saved) {
self::checkStockAlert($offer, $previousStock);
}
return $saved;
}
public static function checkStockAlert($offer, $previousStock)
{
$threshold = (float) $offer->minimum_ondemand;
if ($threshold <= 0) {
return;
}
$crossedThreshold = $previousStock > $threshold
&& $offer->stock_current <= $threshold;
if (! $crossedThreshold) {
return;
}
try {
$offer->load('article');
Mail::to('commande@jardinenvie.com')
->send(new AlerteStock($offer));
Log::info('Stock alert email sent', [
'offer_id' => $offer->id,
'article' => $offer->article->name ?? $offer->article_id,
'stock_current' => $offer->stock_current,
'threshold' => $threshold,
]);
} catch (\Throwable $e) {
Log::error('Failed to send stock alert email', [
'offer_id' => $offer->id,
'stock_current' => $offer->stock_current,
'exception' => $e->getMessage(),
]);
}
}
public static function getStockCurrent($id)