<?php
namespace App\EventListener;
use App\Entity\FurnitureInstance;
use App\Entity\FurnitureInstanceStepVersion;
use App\Entity\FurnitureStock;
use App\Entity\FurnitureStockDateStep;
use App\Entity\OperationOrder;
use App\Service\DataLogger;
use App\Service\FurnitureInstanceService;
use App\Service\FurnitureProductService;
use App\Service\FurnitureStockService;
use App\Service\MailQueueService;
use App\Service\User as UserService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Workflow\Event\Event;
use Symfony\Component\Workflow\Registry;
class FurnitureInstanceWorkflowListener implements EventSubscriberInterface
{
private DataLogger $dataLogger;
private EntityManagerInterface $entityManager;
private MailQueueService $mailQueueService;
private FurnitureProductService $furnitureProductService;
private FurnitureStockService $furnitureStockService;
private FurnitureInstanceService $furnitureInstanceService;
private UserService $userService;
private Registry $workflow;
public function __construct(EntityManagerInterface $entityManager, FurnitureProductService $furnitureProductService, FurnitureStockService $furnitureStockService, FurnitureInstanceService $furnitureInstanceService, UserService $userService, DataLogger $dataLogger, Registry $wokflow, MailQueueService $mailQueueService)
{
$this->entityManager = $entityManager;
$this->mailQueueService = $mailQueueService;
$this->furnitureProductService = $furnitureProductService;
$this->furnitureStockService = $furnitureStockService;
$this->furnitureInstanceService = $furnitureInstanceService;
$this->dataLogger = $dataLogger;
$this->userService = $userService;
$this->workflow = $wokflow;
}
public function onEnter(Event $event): void
{
}
public function onTransition(Event $event): void
{
}
public function onEntered(Event $event): void
{
}
public function onCompleted(Event $event): void
{
$transitionName = $event->getTransition()->getName();
$user = $this->userService->getUser();
/** @var FurnitureInstance $furnitureInstance */
$furnitureInstance = $event->getSubject();
if (method_exists($this, $transitionName)) {
$this->{$transitionName}($furnitureInstance, $transitionName);
}
$furnitureInstanceStepVersion = new FurnitureInstanceStepVersion();
$furnitureInstanceStepVersion->setDate(new \DateTime());
$furnitureInstanceStepVersion->setStep(strtolower(substr((string) $transitionName, 2)));
$furnitureInstanceStepVersion->setUser($user);
$furnitureInstanceStepVersion->setFurnitureInstance($furnitureInstance);
$furnitureInstanceStepVersion->setRecoveryDate($furnitureInstance->getRecoveryDate());
$this->entityManager->persist($furnitureInstanceStepVersion);
}
public function toShipped(FurnitureInstance $furnitureInstance, string $transitionName): void
{
$operationOrder = $this->furnitureInstanceService->getOperationOrder($furnitureInstance);
$this->mailQueueService->addMailQueueEntryType2($operationOrder, $furnitureInstance, 'shipped');
if ($operationOrder instanceof OperationOrder && $operationOrder->getStep() !== 'shipped') {
$toChangeOrderStep = true;
$instances = $this->furnitureProductService->getOrderFurnitureInstances($operationOrder);
if (!empty($instances)) {
foreach ($instances as $instanceItem) {
if ($instanceItem instanceof FurnitureInstance && $instanceItem->getStep() !== 'shipped') {
$toChangeOrderStep = false;
}
}
$workflow = $this->workflow->get($operationOrder, 'order_furniture_step');
if ($toChangeOrderStep === true && $workflow->can($operationOrder, $transitionName)) {
$workflow->apply($operationOrder, $transitionName);
}
}
}
$furnitureStock = $furnitureInstance->getFurnitureStock();
$workflow = $this->workflow->get($furnitureStock, 'furniture_stock_step');
if ($workflow->can($furnitureStock, 'toInProgress1')) {
$workflow->apply($furnitureStock, 'toInProgress1');
}
}
public function toDelivered(FurnitureInstance $furnitureInstance, string $transitionName): void
{
$operationOrder = $this->furnitureInstanceService->getOperationOrder($furnitureInstance);
$this->mailQueueService->addMailQueueEntryType2($operationOrder, $furnitureInstance, 'delivered');
if ($operationOrder instanceof OperationOrder && $operationOrder->getStep() !== 'delivered') {
$toChangeOrderStep = true;
$instances = $this->furnitureProductService->getOrderFurnitureInstances($operationOrder);
if (!empty($instances)) {
foreach ($instances as $instanceItem) {
if ($instanceItem instanceof FurnitureInstance && $instanceItem->getStep() !== 'delivered') {
$toChangeOrderStep = false;
}
}
$workflow = $this->workflow->get($operationOrder, 'order_furniture_step');
if ($toChangeOrderStep === true && $workflow->can($operationOrder, $transitionName)) {
$workflow->apply($operationOrder, $transitionName);
}
}
}
$furnitureStock = $furnitureInstance->getFurnitureStock();
$workflow = $this->workflow->get($furnitureStock, 'furniture_stock_step');
if ($workflow->can($furnitureStock, 'toInProgress1')) {
$workflow->apply($furnitureStock, 'toInProgress1');
}
}
public function toRecovered(FurnitureInstance $furnitureInstance, string $transitionName): void
{
$operationOrder = $this->furnitureInstanceService->getOperationOrder($furnitureInstance);
if ($operationOrder instanceof OperationOrder && $operationOrder->getStep() !== 'finishedClosed') {
$toChangeOrderStep = true;
$instances = $this->furnitureProductService->getOrderFurnitureInstances($operationOrder);
if (!empty($instances)) {
foreach ($instances as $instanceItem) {
if ($instanceItem instanceof FurnitureInstance && $instanceItem->getStep() !== 'recovered') {
$toChangeOrderStep = false;
}
}
$workflow = $this->workflow->get($operationOrder, 'order_furniture_step');
if ($toChangeOrderStep === true && $workflow->can($operationOrder, 'toFinishedClosed')) {
$workflow->apply($operationOrder, 'toFinishedClosed');
}
}
}
$furnitureStock = $furnitureInstance->getFurnitureStock();
$workflow = $this->workflow->get($furnitureStock, 'furniture_stock_step');
if ($workflow->can($furnitureStock, 'toFree')) {
$workflow->apply($furnitureStock, 'toFree');
}
}
public function toUpdateRefused(FurnitureInstance $furnitureInstance, string $transitionName): void
{
$instanceStepVersion = null;
$instanceStepVersions = $this->entityManager->getRepository(FurnitureInstanceStepVersion::class)->findLastGoodStepVersion($furnitureInstance);
if (isset($instanceStepVersions[0])) {
$instanceStepVersion = $instanceStepVersions[0];
}
if ($instanceStepVersion instanceof FurnitureInstanceStepVersion) {
$furnitureInstance->setRecoveryDate($instanceStepVersion->getRecoveryDate());
$furnitureInstance->setStep('shipped');
$furnitureInstance = $this->furnitureInstanceService->populateMailDateField($furnitureInstance);
$this->recalculateStockCalendar($furnitureInstance);
$this->entityManager->persist($furnitureInstance);
$this->dataLogger->add('Revert recoveryDate : ' . $instanceStepVersion->getId(), 'furnitureInstanceWorkflow', $furnitureInstance->getId(), 'info');
}
}
public function toAwaitingDelivery(FurnitureInstance $furnitureInstance, string $transitionName): void
{
$furnitureStock = $furnitureInstance->getFurnitureStock();
$this->recalculateStockCalendar($furnitureInstance);
$workflow = $this->workflow->get($furnitureStock, 'furniture_stock_step');
if ($workflow->can($furnitureStock, 'toReserved')) {
$workflow->apply($furnitureStock, 'toReserved');
}
}
public function toAbandonned(FurnitureInstance $furnitureInstance, string $transitionName): void
{
$furnitureStock = $furnitureInstance->getFurnitureStock();
$operationOrder = $furnitureInstance->getOperationOrderFurnitureLine()->getOperationOrderFurniture();
$furnitureStockDateSteps = $this->entityManager->getRepository(FurnitureStockDateStep::class)->findBy([
'furnitureStock' => $furnitureStock,
'operationOrder' => $operationOrder,
]);
if (!empty($furnitureStockDateSteps)) {
foreach ($furnitureStockDateSteps as $furnitureStockDateStep) {
$furnitureStock->removeFurnitureStockDateStep($furnitureStockDateStep);
}
}
/*
$workflow = $this->workflow->get($furnitureStock, 'furniture_stock_step');
if ($workflow->can($furnitureStock, 'toFree')) {
$workflow->apply($furnitureStock, 'toFree');
}
*/
}
public function toExtendToTransmit(FurnitureInstance $furnitureInstance, string $transitionName): void
{
$this->recalculateStockCalendar($furnitureInstance);
}
public function toRecoveryToTransmit(FurnitureInstance $furnitureInstance, string $transitionName): void
{
$this->recalculateStockCalendar($furnitureInstance);
}
public function onLeave(Event $event): void
{
}
public static function getSubscribedEvents(): array
{
return [
'workflow.furniture_instance_step.leave' => 'onLeave',
'workflow.furniture_instance_step.transition' => 'onTransition',
'workflow.furniture_instance_step.enter' => 'onEnter',
'workflow.furniture_instance_step.entered' => 'onEntered',
'workflow.furniture_instance_step.completed' => 'onCompleted',
];
}
private function recalculateStockCalendar(FurnitureInstance $furnitureInstance): void
{
$furnitureStock = $furnitureInstance->getFurnitureStock();
if ($furnitureStock instanceof FurnitureStock) {
$operationOrder = $furnitureInstance->getOperationOrderFurnitureLine()->getOperationOrderFurniture();
$this->furnitureStockService->removeStockOrderToCalendar($furnitureInstance->getFurnitureStock(), $operationOrder);
$this->furnitureStockService->addStockToCalendar($furnitureStock, $furnitureInstance->getDeliveryDate(), $furnitureInstance->getRecoveryDate(), $operationOrder);
}
}
}