Inicio
NexoPOS

Evento de campos despachables del modelo

El evento de campos despachables es un concepto que garantiza el disparo de eventos cuando cambia una propiedad del modelo. A diferencia de los eventos regulares del modelo, que se despachan cuando se realiza una acción específica (guardar, actualizar, eliminar, etc.), aquí hay una implementación profunda que solo se activa si un atributo específico de un modelo ha cambiado.

La razón de esta implementación fue evitar despachar y escuchar eventos cuando no es necesario. Por ejemplo, un pedido en NexoPOS se puede actualizar de varias maneras. Cada vez que se actualiza el pedido, contamos con listeners predeterminados listos para realizar una acción específica. ¿No sería mejor que, cuando cambia el cliente asignado, calculemos informes para el cliente anterior y el reciente? ¿No sería mejor que pudiéramos notificar al conductor solo cuando el estado de la entrega pase de “pendiente” a “listo para la entrega”? Esa es la idea de esta funcionalidad.

Implementación

La implementación de esa funcionalidad consiste únicamente en proporcionar un array $dispatchableFieldsEvents en el modelo en el que queremos despachar el evento. En ese modelo, proporcionaremos la propiedad y los eventos relacionados así:

<?php
namespace Modules\YourModule\Models;

use App\Models\NsModel;
use Modules\YourModule\Events\DeliveryChangedEvent;

class Order extends NsModel
{
    public $dispatchableFieldsEvents  = [
      'delivery_status' =>  DeliveryChangedEvent::class
    ];
}

Ahora necesitamos definir el evento, ya que no solo recibe el modelo como parámetro, sino también el valor anterior y el nuevo de la propiedad:

<?php
namespace Modules\YourModule\Events;

use App\Models\Order;

class DeliveryChangedEvent
{
    public function __construct( public Order $order, public mixed $previous, public mixed $new )
    {
        // ...
    }
}

Desde aquí, puedes escuchar de forma segura este evento desde nuestro listener de eventos así:

<?php 
namespace Modules\YourModule\Listeners;

use Modules\YourModule\Events\DeliveryChangedEvent;
use Moduels\YourModules\Services\DriverService;

class DeliveryChangedEventListener
{
    public function __construct( public DriverService $driverService ){
    {
        // ...
    }
      
    public function handle( DeliveryChangedEvent $event )
    {
          if ( $event->previous === 'pending' && $event->new === 'ready-for-delivery' ) {
              $this->driverService->notifyAssignedDriver( $event->order );
          }
    }
}