src/EventSubscriber/Expediting/ExpeditablesShippingStatusWatcher.php line 64
<?php
namespace App\EventSubscriber\Expediting;
use App\Doctrine\Type\Expediting\ExpeditableStatus;
use App\Doctrine\Type\Expediting\ShipmentType;
use App\Doctrine\Type\Expediting\ShippingSegmentStatus;
use App\Entity\Expediting\ShippingSegment;
use App\Event\Expediting\ShipmentCancelationEvent;
use App\Event\Expediting\ShipmentReschedulingEvent;
use App\Event\Expediting\ShipmentStatusUpdateEvent;
use App\Event\Expediting\ShippingSegmentEventInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
readonly class ExpeditablesShippingStatusWatcher implements EventSubscriberInterface
{
use ExpeditablesStatusUpdaterTrait;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly EventDispatcherInterface $eventDispatcher,
) {}
public static function getSubscribedEvents(): array
{
return [
ShipmentStatusUpdateEvent::IDENTIFIER => ['handleUpdate', 0],
ShipmentReschedulingEvent::IDENTIFIER => ['handleUpdate', 0],
ShipmentCancelationEvent::IDENTIFIER => ['handleCancelation', 0],
];
}
public function handleUpdate(ShippingSegmentEventInterface $event): void
{
$shippingSegment = $event->getShippingSegment();
switch ($shippingSegment->getStatus()) {
case ShippingSegmentStatus::STARTED:
$status = in_array(ShipmentType::PICKUP, $shippingSegment->getTypes())
? ExpeditableStatus::COLLECTED
: ExpeditableStatus::DEPARTED;
break;
case ShippingSegmentStatus::COMPLETED:
$status = in_array(ShipmentType::PICKUP, $shippingSegment->getTypes())
? ExpeditableStatus::RECEIVED
: ExpeditableStatus::ARRIVED;
break;
case ShippingSegmentStatus::CANCELED:
$this->eventDispatcher->dispatch(new ShipmentCancelationEvent($shippingSegment), ShipmentCancelationEvent::IDENTIFIER);
return;
case ShippingSegmentStatus::PLANNED:
case ShippingSegmentStatus::APPROVED:
case ShippingSegmentStatus::BOOKED:
return;
}
if ($status instanceof ExpeditableStatus) {
$this->process($shippingSegment, $status);
}
}
public function handleCancelation(ShipmentCancelationEvent $event): void
{
$shippingSegment = $event->getShippingSegment();
$status = in_array(ShipmentType::PICKUP, $shippingSegment->getTypes())
? ExpeditableStatus::READY_FOR_PICKUP
: ExpeditableStatus::MARSHALLED;
$this->process($shippingSegment, $status);
}
private function process(ShippingSegment $shippingSegment, ExpeditableStatus $status): void
{
$shippingPlan = $shippingSegment->getShippingPlan();
if ($workOrder = $shippingPlan->getWorkOrder()) {
$this->updateExpeditables($workOrder->getPackages(), $status);
} elseif ($shipment = $shippingPlan->getShipment()) {
$this->updateExpeditables($shipment->getPackages(), $status);
}
}
}