<?php
namespace App\V4\EventSubscriber\Quote;
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
use App\Model\ProspectSubscription\ProspectSubscription;
use App\V4\DataPersister\AbstractWithoutRequestDataPersister;
use App\V4\EventSubscriber\AbstractSubscriber;
use App\V4\Form\Type\ProspectSubscription\ProspectSubscriptionType;
use App\V4\Model\Prospect\Prospect;
use App\V4\Model\Quote\Quote;
use App\V4\Model\QuoteLineInfo\QuoteLineInfo;
use App\V4\Model\QuoteState\QuoteState;
use DateTime;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Security\Core\Security;
class QuotePersistEventSubscriber extends AbstractSubscriber implements EventSubscriberInterface
{
/**
* @var CollectionDataProviderInterface
*/
private $collectionDataProvider;
/**
* @var ItemDataProviderInterface
*/
private $itemDataProvider;
/**
* @var FormFactoryInterface
*/
private $formFactory;
/**
* @var DataPersisterInterface
*/
private $dataPersister;
/**
* @var Security
*/
private $security;
/**
* @param CollectionDataProviderInterface $collectionDataProvider
* @param ItemDataProviderInterface $itemDataProvider
* @param FormFactoryInterface $formFactory
* @param DataPersisterInterface $dataPersister
* @param Security $security
*/
public function __construct(
CollectionDataProviderInterface $collectionDataProvider,
ItemDataProviderInterface $itemDataProvider,
FormFactoryInterface $formFactory,
DataPersisterInterface $dataPersister,
Security $security
) {
$this->collectionDataProvider = $collectionDataProvider;
$this->itemDataProvider = $itemDataProvider;
$this->formFactory = $formFactory;
$this->dataPersister = $dataPersister;
$this->security = $security;
}
/**
* @param FormEvent $event
*
* @return bool
*/
public function supports(FormEvent $event): bool
{
return $event->getData() instanceof Quote
&& $event->getData()->getStatus() instanceof QuoteState
&& $event->getData()->getStatus()->getIsWon()
;
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return [
FormEvents::POST_SUBMIT => 'onPostSubmit',
];
}
/**
* @param FormEvent $event
*
* @throws ResourceClassNotSupportedException
*/
public function onPostSubmit(FormEvent $event): void
{
if (!$this->supports($event) || $this->isIdAlreadyManaged($event->getData()->getId(), get_class($this))) {
return;
}
/** @var Quote $quote */
$quote = $event->getData();
$prospectSubscriptions = $this->collectionDataProvider->getCollection(ProspectSubscription::class, null, [
'filters' => [
'quote' => $quote->getId(),
],
'transformResponse' => false,
]);
if (!empty($prospectSubscriptions)) {
return;
}
$user = $this->security->getUser();
$prospect = $quote->getProspect() ?? $this->itemDataProvider->getItem(Prospect::class, $quote->getProspectId());
foreach ($quote->getQuoteLines() as $quoteLine) {
if (!$quoteLine->getQuoteLineInfo() instanceof QuoteLineInfo
|| !$quoteLine->getQuoteLineInfo()->hasSubscriptionProduct()) {
continue;
}
$product = $quoteLine->getQuoteLineInfo()->getProduct();
$endAt = $quote->getExpectedSignedAt() instanceof DateTime ? clone $quote->getExpectedSignedAt() : new DateTime();
$endAt->modify(sprintf('+%s %s', $product->getSubscriptionValue(), $product->getSubscriptionUnit()));
$prospectSubscription = (new ProspectSubscription())
->setCustomerId($quote->getCustomerId() ?? $user->getCustomerId())
->setProspect($prospect)
->setQuote($quote)
->setProduct($product)
->setProductName($product->getName())
->setProductDescription($product->getShortDescription())
->setProductReference($product->getReference())
->setBeginAt($quote->getExpectedSignedAt() ?? new DateTime())
->setEndAt($endAt)
;
$prospectSubscriptionForm = $this->formFactory->create(
ProspectSubscriptionType::class,
$prospectSubscription,
['prospectId' => $quote->getProspectId()]
);
$prospectSubscriptionForm->submit(['prospect' => $quote->getProspectId()], false);
if ($prospectSubscriptionForm->isValid() && $prospectSubscriptionForm->isSubmitted()) {
/** @var ProspectSubscription $prospectSubscription */
$prospectSubscription = $prospectSubscriptionForm->getData();
if ($prospectSubscription->getProspect() instanceof Prospect
&& $prospectSubscription->getQuote() instanceof Quote) {
$prospectSubscription->getProspect()->setNormalizeAsIRI(true);
$prospectSubscription->getQuote()->setNormalizeAsIRI(true);
$this->dataPersister->persist($prospectSubscription, [
AbstractWithoutRequestDataPersister::CONTEXT_IS_V4 => true,
]);
$prospectSubscription->getQuote()->setNormalizeAsIRI(false);
}
}
}
}
}