<?php
namespace App\V4\Module\DolibarrApi\EventSubscriber;
use App\DataPersister\AbstractDataPersister;
use App\Export\Builder\ExportBuilderInterface;
use App\Export\Builder\ExporterInterface;
use App\Model\Exception\ModuleNotFoundException;
use App\Security\SecurityConfig;
use App\V4\Event\PostPersistEvent;
use App\V4\EventSubscriber\AbstractSubscriber;
use App\V4\Model\Contact\Contact;
use App\V4\Model\Prospect\Prospect;
use App\V4\Model\Quote\Quote;
use App\V4\Module\DolibarrApi\Controller\QuoteDataPersisterAction;
use App\V4\Module\DolibarrApi\Exception\NotFoundException;
use App\V4\Module\DolibarrApi\Service\ConfigurationService;
use App\V4\Module\DolibarrApi\Service\SendDataService;
use App\V4\Validator\CustomAction\Builder\CustomActionValidatorBuilder;
use App\V4\Validator\CustomActionValidator;
use ReflectionException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class EntityEventSubscriber extends AbstractSubscriber implements EventSubscriberInterface
{
/**
* @var SendDataService
*/
private $sendDataService;
/**
* @var ConfigurationService
*/
private $configurationService;
/**
* @var CustomActionValidatorBuilder
*/
private $customActionValidatorBuilder;
/**
* @var ExportBuilderInterface
*/
private $exportBuilder;
/**
* @var Security
*/
private $security;
public function __construct(
SendDataService $sendDataService,
ConfigurationService $configurationService,
CustomActionValidatorBuilder $customActionValidatorBuilder,
ExportBuilderInterface $exportBuilder,
Security $security
) {
$this->sendDataService = $sendDataService;
$this->configurationService = $configurationService;
$this->customActionValidatorBuilder = $customActionValidatorBuilder;
$this->exportBuilder = $exportBuilder;
$this->security = $security;
}
public static function getSubscribedEvents(): array
{
return [
PostPersistEvent::NAME => 'onPostPersist',
];
}
public function supports(PostPersistEvent $event): bool
{
return $this->security->isGranted(SecurityConfig::MODULE_DOLIBARR_API)
&& (
$event->getAfter() instanceof Prospect
|| $event->getAfter() instanceof Contact
|| $event->getAfter() instanceof Quote
)
&& $this->supportsConfiguration($event)
;
}
/**
* @param PostPersistEvent $event
*
* @throws ExceptionInterface
* @throws ModuleNotFoundException
* @throws NotFoundException
* @throws ReflectionException
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function onPostPersist(PostPersistEvent $event)
{
$context = $event->getContext();
if (!empty($context[AbstractDataPersister::CONTEXT_ORIGIN]) &&
QuoteDataPersisterAction::FROM_DOLIBARR_PERSIST === $context[AbstractDataPersister::CONTEXT_ORIGIN]
) {
return;
}
$entity = $event->getAfter();
if (!$this->supports($event) || $this->isIdAlreadyManaged($event->getAfter()->getId(), get_class($this))) {
return;
}
if ($entity instanceof Prospect) {
/* @var Prospect $entity */
$this->sendDataService->sendProspectToService(
get_class($entity),
$entity
);
}
if ($entity instanceof Contact) {
/* @var Contact $entity */
$this->sendDataService->sendProspectContactToService(
get_class($entity),
$entity
);
}
if ($entity instanceof Quote) {
$dolibarrStatus = $entity->getStatus()->getIsWon() ? 2 : ($entity->getStatus()->getIsLost() ? 3 : null);
if (null !== $dolibarrStatus) {
/* @var Quote $entity */
$this->sendDataService->sendQuoteToService(
get_class($entity),
$entity,
['status' => $dolibarrStatus]
);
}
}
}
private function supportsConfiguration(PostPersistEvent $event): bool
{
$configuration = $this->configurationService->getEventListenersByEntity(get_class($event->getAfter()));
if (!array_key_exists('onPostPersist', $configuration)) {
return false;
}
if (empty($configuration['onPostPersist'])) {
return true;
}
/** @var Prospect|Quote $object */
$object = $event->getAfter();
foreach ($configuration['onPostPersist'][CustomActionValidator::CUSTOM_ACTION_CONDITIONS] as $condition) {
$value = $this->exportBuilder
->getExporter($object, $condition[CustomActionValidator::CUSTOM_ACTION_CONDITIONS_KEY], ExporterInterface::EXPORT_TYPE_LISTING)
->convert($object, $condition[CustomActionValidator::CUSTOM_ACTION_CONDITIONS_KEY]);
if (isset($condition[CustomActionValidator::CUSTOM_ACTION_CONDITIONS_KEY])
&& !$this->customActionValidatorBuilder->getValidator($value, $condition)->isValid($value, $condition)) {
return false;
}
}
return true;
}
}