ERP/BillingRequestsBundle/EventSubscriber/BillingRequestsAutomationSubscriber.php line 85

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace ERP\BillingRequestsBundle\EventSubscriber;
  4. use ApiPlatform\Core\Api\IriConverterInterface;
  5. use ApiPlatform\Core\EventListener\EventPriorities;
  6. use App\Entity\Project;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use ERP\BillingRequestsBundle\Entity\BillingRequestAutomation;
  9. use ERP\BillingRequestsBundle\Entity\ProjectBillingRequestAutomationInterface;
  10. use ERP\BillingRequestsBundle\Factory\BillingRequestAutomationFactory;
  11. use ERP\BillingRequestsBundle\Factory\BillingRequestFactory;
  12. use ERP\BillingRequestsBundle\Repository\BillingRequestAutomationRepository;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpFoundation\RequestStack;
  16. use Symfony\Component\HttpKernel\Event\RequestEvent;
  17. use Symfony\Component\HttpKernel\Event\ViewEvent;
  18. use Symfony\Component\HttpKernel\KernelEvents;
  19. use Symfony\Component\Security\Core\Security;
  20. class BillingRequestsAutomationSubscriber implements EventSubscriberInterface
  21. {
  22.     /**
  23.      * @var BillingRequestFactory
  24.      */
  25.     private $billingRequestFactory;
  26.     /**
  27.      * @var EntityManagerInterface
  28.      */
  29.     private $entityManager;
  30.     /**
  31.      * @var IriConverterInterface
  32.      */
  33.     private $iriConverter;
  34.     /**
  35.      * @var BillingRequestAutomationFactory
  36.      */
  37.     private $automationFactory;
  38.     /**
  39.      * @var RequestStack
  40.      */
  41.     private $requestStack;
  42.     /**
  43.      * @var Security
  44.      */
  45.     private $security;
  46.     /**
  47.      * BillingRequestsAutomationSubscriber constructor.
  48.      */
  49.     public function __construct(
  50.         BillingRequestFactory $billingRequestFactory,
  51.         BillingRequestAutomationFactory $automationFactory,
  52.         EntityManagerInterface $entityManager,
  53.         IriConverterInterface $iriConverter,
  54.         RequestStack $requestStack,
  55.         Security $security
  56.     ) {
  57.         $this->billingRequestFactory $billingRequestFactory;
  58.         $this->automationFactory $automationFactory;
  59.         $this->entityManager $entityManager;
  60.         $this->iriConverter $iriConverter;
  61.         $this->requestStack $requestStack;
  62.         $this->security $security;
  63.     }
  64.     public static function getSubscribedEvents()
  65.     {
  66.         return [
  67.             KernelEvents::VIEW => [
  68.                 ['removeExistingAutomations'EventPriorities::PRE_VALIDATE],
  69.                 ['onCreateProject'EventPriorities::POST_WRITE],
  70.                 ['onSerializeAutomationSetup'EventPriorities::POST_VALIDATE],
  71. //                ['onDeserializeAutomationSetup', EventPriorities::PRE_SERIALIZE],
  72.             ],
  73.             KernelEvents::REQUEST => [
  74.                 ['checkInstallmentsChange'EventPriorities::PRE_DESERIALIZE],
  75.             ],
  76.         ];
  77.     }
  78.     public function removeExistingAutomations(ViewEvent $event): void
  79.     {
  80.         if (
  81.             in_array($event->getRequest()->getMethod(), [Request::METHOD_PATCHRequest::METHOD_PUT]) &&
  82.             is_object($project $event->getControllerResult()) &&
  83.             $project instanceof Project &&
  84.             $project instanceof ProjectBillingRequestAutomationInterface
  85.         ) {
  86.             $request $this->requestStack->getCurrentRequest();
  87.             $content json_decode($request->getContent(), true);
  88.             if (
  89.                 isset($content['create_billing_requests_automatically'])
  90.                 && false === $content['create_billing_requests_automatically']
  91.             ) {
  92.                 $project->setAutomationConfig([]);
  93.             }
  94.             if (
  95.                 $project->isCreateBillingRequestsAutomatically()
  96.                 && $project->getBillingRequestAutomations()->count()
  97.             ) {
  98.                 /** @var BillingRequestAutomationRepository $repo */
  99.                 $repo $this->entityManager->getRepository(BillingRequestAutomation::class);
  100.                 /** @var array|BillingRequestAutomation[] $automations */
  101.                 foreach ($repo->findBy(['project' => $project]) as $automation) {
  102.                     if ($automation instanceof BillingRequestAutomation) {
  103.                         $this->entityManager->remove($automation);
  104.                         $this->entityManager->flush();
  105.                     }
  106.                 }
  107.             }
  108.         }
  109.     }
  110.     public function checkInstallmentsChange(RequestEvent $event): void
  111.     {
  112.         if (
  113.             in_array($event->getRequest()->getMethod(), [Request::METHOD_PATCHRequest::METHOD_PUT]) &&
  114.             is_object($project $event->getRequest()->attributes->get('data')) &&
  115.             $project instanceof Project &&
  116.             $project instanceof ProjectBillingRequestAutomationInterface
  117.         ) {
  118.             $request $this->requestStack->getCurrentRequest();
  119.             $content json_decode($request->getContent(), true);
  120.             if (
  121.                 $project->isCreateBillingRequestsAutomatically()
  122.                 && $project->getBillingRequestAutomations()->count()
  123.                 && isset($content['installments'])
  124.                 && $content['installments'] !== $project->getInstallments()
  125.             ) {
  126.                 /** @var BillingRequestAutomationRepository $repo */
  127.                 $repo $this->entityManager->getRepository(BillingRequestAutomation::class);
  128.                 /** @var array|BillingRequestAutomation[] $automations */
  129.                 foreach ($repo->findByProjectUnusedAnytime($project) as $automation) {
  130.                     if ($automation instanceof BillingRequestAutomation) {
  131.                         $this->entityManager->remove($automation);
  132.                         $this->entityManager->flush();
  133.                     }
  134.                 }
  135.                 $request->attributes->set(
  136.                     'data',
  137.                     $project
  138.                 );
  139.             }
  140.         }
  141.     }
  142.     public function onSerializeAutomationSetup(ViewEvent $event): void
  143.     {
  144.         if (
  145.             in_array($event->getRequest()->getMethod(), [Request::METHOD_POSTRequest::METHOD_PATCHRequest::METHOD_PUT]) &&
  146.             is_object($project $event->getControllerResult()) &&
  147.             $project instanceof Project &&
  148.             $project instanceof ProjectBillingRequestAutomationInterface &&
  149.             $project->isCreateBillingRequestsAutomatically()
  150.         ) {
  151.             $automationSetup = [
  152.                 'payment_date' => $project->getPaymentDate(),
  153.                 'installments' => $project->getInstallments(),
  154.                 'billing_request_description' => $project->getBillingRequestDescription(),
  155.                 'payment_method' => $project->getPaymentMethod(),
  156.                 'payment_term' => $project->getPaymentTerm(),
  157.                 'payment_category' => $project->getPaymentCategory(),
  158.                 'payment_department' => $project->getPaymentDepartment(),
  159.                 'payment_amount' => $project->getPaymentAmount(),
  160.                 'payment_billing_type' => $project->getPaymentBillingType(),
  161.                 'payment_billing_frequency' => $project->getPaymentBillingFrequency(),
  162.                 'payment_additional_subscribers' => $project->getPaymentAdditionalSubscribers(),
  163.                 'interest_rate' => $project->getInterestRate(),
  164.                 'amount_by_hours_worked' => $project->isAmountByHoursWorked(),
  165.                 'payment_default_hourly_rate' => $project->getPaymentDefaultHourlyRate(),
  166.                 'message_dismissed' => $this->messageDismissedByUser($project),
  167.             ];
  168.             $project->setAutomationConfig($automationSetup);
  169.         }
  170.     }
  171.     public function onCreateProject(ViewEvent $event): void
  172.     {
  173.         if (
  174.             in_array($event->getRequest()->getMethod(), [Request::METHOD_POSTRequest::METHOD_PATCHRequest::METHOD_PUT]) &&
  175.             is_object($project $event->getControllerResult()) &&
  176.             $project instanceof ProjectBillingRequestAutomationInterface &&
  177.             $project->isCreateBillingRequestsAutomatically()
  178.         ) {
  179.             $automation $this->automationFactory->createFromProject($project);
  180.             if (is_object($automation)) {
  181.                 $this->entityManager->persist($automation);
  182.                 $this->entityManager->flush();
  183.             }
  184.         }
  185.     }
  186.     private function messageDismissedByUser(Project $project): array
  187.     {
  188.         $messageDismissed $project->getAutomationConfig()['message_dismissed'] ?? [];
  189.         $userIri $this->iriConverter->getIriFromItem($this->security->getUser());
  190.         if (!$messageDismissed && is_null($project->isMessageDismissed($userIri))) {
  191.             $project->setMessageDismissed(false);
  192.         }
  193.         foreach ($messageDismissed as &$item) {
  194.             if ($item['user'] === $userIri) {
  195.                 $item['status'] = $project->isMessageDismissed($userIri);
  196.                 return $messageDismissed;
  197.             }
  198.         }
  199.         $messageDismissed[] = [
  200.             'user' => $userIri,
  201.             'status' => $project->isMessageDismissed($userIri),
  202.         ];
  203.         return $messageDismissed;
  204.     }
  205. }