70 lines
2.3 KiB
PHP
70 lines
2.3 KiB
PHP
<?php namespace App\Observers;
|
|
/**
|
|
* @copyright (c) 2025 Notsoweb Software (https://notsoweb.com) - All Rights Reserved
|
|
*/
|
|
|
|
use App\Models\InventoryWarehouse;
|
|
use App\Models\User;
|
|
use App\Notifications\UserNotification;
|
|
|
|
/**
|
|
* Observer de stock por almacén
|
|
*
|
|
* Envía notificación a administradores cuando el stock de un producto
|
|
* cruza el umbral mínimo (de disponible a bajo stock).
|
|
*
|
|
* @author Moisés Cortés C. <moises.cortes@notsoweb.com>
|
|
*
|
|
* @version 1.0.0
|
|
*/
|
|
class InventoryWarehouseObserver
|
|
{
|
|
/**
|
|
* Roles que reciben alertas de stock bajo
|
|
*/
|
|
protected array $notifiableRoles = ['developer', 'admin'];
|
|
|
|
/**
|
|
* Umbral por defecto cuando min_stock no está configurado
|
|
*/
|
|
protected int $defaultThreshold = 5;
|
|
|
|
/**
|
|
* Detectar cuando el stock cruza el umbral mínimo hacia abajo
|
|
*/
|
|
public function updated(InventoryWarehouse $inventoryWarehouse): void
|
|
{
|
|
$previousStock = (float) $inventoryWarehouse->getOriginal('stock');
|
|
$currentStock = (float) $inventoryWarehouse->stock;
|
|
$threshold = (float) ($inventoryWarehouse->min_stock ?? $this->defaultThreshold);
|
|
|
|
// Solo notificar si el stock CRUZÓ el umbral (no en cada update mientras ya esté bajo)
|
|
if ($previousStock >= $threshold && $currentStock < $threshold) {
|
|
$this->notifyLowStock($inventoryWarehouse, $currentStock);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enviar notificación de stock bajo a usuarios con rol relevante
|
|
*/
|
|
protected function notifyLowStock(InventoryWarehouse $inventoryWarehouse, float $currentStock): void
|
|
{
|
|
$inventoryWarehouse->load('inventory', 'warehouse');
|
|
|
|
$productName = $inventoryWarehouse->inventory?->name ?? 'Producto desconocido';
|
|
$warehouseName = $inventoryWarehouse->warehouse?->name ?? 'Almacén desconocido';
|
|
|
|
$users = User::role($this->notifiableRoles)->get();
|
|
|
|
foreach ($users as $user) {
|
|
$user->notify(new UserNotification(
|
|
title: 'Stock bajo: ' . $productName,
|
|
description: "El producto \"{$productName}\" tiene {$currentStock} unidad(es) disponible(s) en \"{$warehouseName}\".",
|
|
type: 'warning',
|
|
timeout: 30,
|
|
save: true,
|
|
));
|
|
}
|
|
}
|
|
}
|