- <?php
- namespace App\EventSubscriber;
- use ApiPlatform\Core\EventListener\EventPriorities;
- use App\Entity\AbstractPeople;
- use App\Entity\Property;
- use App\Entity\Reference\ReferencePropertyDomain;
- use App\Entity\Reference\ReferencePropertyServiceType;
- use App\Entity\Reference\ReferencePropertyStatus;
- use App\Manager\Property\AssignPropertyRecommendationInterface;
- use App\Manager\Property\PropertyReferenceGeneratorInterface;
- use App\Message\GenerateBusinessIndicationMandateMessage;
- use Doctrine\ORM\EntityManagerInterface;
- use Symfony\Component\EventDispatcher\EventSubscriberInterface;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpKernel\Event\ViewEvent;
- use Symfony\Component\HttpKernel\KernelEvents;
- use Symfony\Component\HttpKernel\Event\TerminateEvent;
- use Symfony\Component\Messenger\MessageBusInterface;
- use Psr\Log\LoggerInterface;
- class PropertySubscriber implements EventSubscriberInterface
- {
-     public const BUSINESS_INDICATION_ALLOWED_METHODS = [
-      Request::METHOD_POST,
-      Request::METHOD_PUT,
-      Request::METHOD_PATCH
-     ];
-     public const BUSINESS_INDICATION_ALLOWED_STATUS_CODE = [
-         Response::HTTP_CREATED
-     ];
-     private EntityManagerInterface $entityManager;
-     private PropertyReferenceGeneratorInterface $referenceGenerator;
-     private AssignPropertyRecommendationInterface $assignPropertyRecommendation;
-     private MessageBusInterface $bus;
-     private LoggerInterface $logger;
-     public function __construct(
-         EntityManagerInterface $entityManager,
-         PropertyReferenceGeneratorInterface $referenceGenerator,
-         AssignPropertyRecommendationInterface $assignPropertyRecommendation,
-         MessageBusInterface $bus,
-         LoggerInterface $logger
-     ) {
-         $this->entityManager = $entityManager;
-         $this->referenceGenerator = $referenceGenerator;
-         $this->assignPropertyRecommendation = $assignPropertyRecommendation;
-         $this->bus = $bus;
-         $this->logger = $logger;
-     }
-     /**
-      * @param ViewEvent $event
-      */
-     public function postUpdate(ViewEvent $event): void
-     {
-         $property = $event->getControllerResult();
-         $method = $event->getRequest()->getMethod();
-         if (!$property instanceof Property || Request::METHOD_PUT !== $method) {
-             return;
-         } elseif (
-             $property->getReferencePropertyStatus()->getName() ===
-             ReferencePropertyStatus::REFERENCE_PROPERTY_STATUS_INVALIDE
-         ) {
-             $this->assignPropertyRecommendation->assignRecommendation($property);
-             $this->entityManager->flush();
-         }
-         if ($property->getVMandate()) {
-             $mandate = $property->getVMandate()[0];
-             $mandate->setMaximumPrice($property->getMinimalPrice());
-             $this->entityManager->flush();
-         }
-         $hasUpdatedArea = false;
-         foreach ($property->getMandates() as $mandate) {
-             if ($mandate->getMinimalArea() !== $property->getMinimalArea()) {
-                 $hasUpdatedArea = true;
-                 $mandate->setMinimalArea($property->getMinimalArea());
-                 $this->entityManager->persist($mandate);
-             }
-             if ($mandate->getMaximalArea() !== $property->getMaximalArea()) {
-                 $hasUpdatedArea = true;
-                 $mandate->setMaximalArea($property->getMaximalArea());
-                 $this->entityManager->persist($mandate);
-             }
-         }
-         if ($hasUpdatedArea) {
-             $this->entityManager->flush();
-         }
-     }
-     public function generateKey($event): void
-     {
-         $property = $event->getControllerResult();
-         $method = $event->getRequest()->getMethod();
-         if (!$property instanceof Property || Request::METHOD_POST !== $method) {
-             return;
-         }
-         $this->referenceGenerator->generate($property);
-     }
-     public function handleBusinessIndicationProcess(TerminateEvent $event): void
-     {
-         $entity = $event->getRequest()->attributes->get('_api_resource_class');
-         $method = $event->getRequest()->getMethod();
-         $responseStatus = $event->getResponse()->getStatusCode();
-         if (
-             $entity === Property::class
-             && in_array($method, self::BUSINESS_INDICATION_ALLOWED_METHODS, true)
-             && in_array($responseStatus, self::BUSINESS_INDICATION_ALLOWED_STATUS_CODE, true)
-         ) {
-             $responseContent = json_decode($event->getResponse()->getContent(), true);
-             if ($this->isBusinessIndicationProcess($responseContent)) {
-                 try {
-                     $message = new GenerateBusinessIndicationMandateMessage((int) $responseContent['id']);
-                     $this->bus->dispatch($message);
-                 } catch (\Throwable $exception) {
-                     $this->logger->error(
-                         'Failed to publish GeneratBusinessIndicationMandateMessage !',
-                         [
-                             'trace' => $exception->getTrace(),
-                             'line' => $exception->getLine(),
-                             'message' => $exception->getMessage(),
-                             'file' => $exception->getFile(),
-                         ]
-                     );
-                 }
-             }
-         }
-     }
-     /**
-      * @param array $propertyResponse
-      *
-      * @return bool
-      */
-     private function isBusinessIndicationProcess(array $propertyResponse): bool
-     {
-         return
-             $propertyResponse['referencePropertyDomain']['code'] ===
-             ReferencePropertyDomain::REFERENCE_CODE_PROPERTY_DOMAIN_NEW
-             && $propertyResponse['referenceServiceType']['code'] ===
-             ReferencePropertyServiceType::REFERENCE_CODE_PROPERTY_SERVICE_TYPE_SELL
-             && $propertyResponse['contact']['personType'] === AbstractPeople::PERSON_TYPE_MORAL
-             && $propertyResponse['contact']['isBusinessIndication'];
-     }
-     public static function getSubscribedEvents(): array
-     {
-         return [
-             KernelEvents::VIEW => [
-                 ['postUpdate', EventPriorities::POST_WRITE],
-                 ['generateKey', EventPriorities::POST_WRITE],
-             ],
-             KernelEvents::TERMINATE => [['handleBusinessIndicationProcess', 0]]
-         ];
-     }
- }
-