src/EventSubscriber/QuotationWorkflowSubscriber.php line 122

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Entity\Event as SubscriptionEvent;
  4. use App\Entity\Invoice;
  5. use App\Entity\PriceInquiry;
  6. use App\Repository\CustomerQuotationsRepository;
  7. use App\Security\Voters\UserVoter;
  8. use App\Service\Constants\InvoiceType;
  9. use Doctrine\Common\Util\ClassUtils;
  10. use App\Repository\SubscriptionRepository;
  11. use App\Service\RabbitMQ\RabbitMQDispatcher;
  12. use App\Service\Subscription\SubscriptionService;
  13. use App\Service\UserLog;
  14. use Doctrine\ORM\EntityManagerInterface;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\Workflow\Event\GuardEvent;
  17. use Symfony\Component\Security\Core\Security;
  18. use Symfony\Component\Workflow\Event\Event;
  19. use App\Service\Api\PipeDriveService;
  20. use App\Service\Mailing\MailContentQuotation;
  21. use App\Service\Mailing\MailingService;
  22. use App\Service\Log\QuotationLogService;
  23. use Symfony\Component\Workflow\Registry;
  24. use App\Service\Invoice\InvoiceService;
  25. class QuotationWorkflowSubscriber implements EventSubscriberInterface
  26. {
  27.     private Security $security;
  28.     private QuotationLogService $logService;
  29.     private UserLog $userLog;
  30.     private Registry $workflows;
  31.     private RabbitMQDispatcher $rabbitMQDispatcher;
  32.     private CustomerQuotationsRepository $quotationRepo;
  33.     private InvoiceService $invoiceService;
  34.     private SubscriptionService $subscriptionService;
  35.     private SubscriptionRepository $subscriptionRepo;
  36.     private EntityManagerInterface $em;
  37.     public function __construct(
  38.         Security $security,
  39.         CustomerQuotationsRepository $quotationRepo,
  40.         QuotationLogService $logService,
  41.         Registry $workflows,
  42.         RabbitMQDispatcher $rabbitMQDispatcher,
  43.         UserLog $userLog,
  44.         InvoiceService $invoiceService,
  45.         SubscriptionRepository $subscriptionRepo,
  46.         SubscriptionService $subscriptionService,
  47.         EntityManagerInterface       $em
  48.     )
  49.     {
  50.         $this->em $em;
  51.         $this->workflows $workflows;
  52.         $this->security $security;
  53.         $this->rabbitMQDispatcher $rabbitMQDispatcher;
  54.         $this->subscriptionService $subscriptionService;
  55.         $this->quotationRepo $quotationRepo;
  56.         $this->logService $logService;
  57.         $this->userLog $userLog;
  58.         $this->invoiceService $invoiceService;
  59.         $this->subscriptionRepo $subscriptionRepo;
  60.     }
  61.     public static function getSubscribedEvents()
  62.     {
  63.         return [
  64.             'workflow.quotation_status.guard.to_ready' => ['toReadyGuard'],
  65.             'workflow.quotation_status.guard.to_deleted' => ['canBeDeletedGuard'],
  66.             'workflow.quotation_status.guard.to_inquiries_sent' => ['inquiriesSentGuard'],
  67.             'workflow.quotation_status.guard.to_offers_partially_received' => ['offersPartiallyReceivedGuard'],
  68.             'workflow.quotation_status.guard.to_offers_received' => ['offersReceivedGuard'],
  69.             'workflow.quotation_status.guard.to_ordered' => ['toOrderedGuard'],
  70.             'workflow.quotation_status.guard.to_waiting_payment' => ['toWaitingPaymentGuard'],
  71.             'workflow.quotation_status.guard.to_accepted' => ['toAcceptedGuard'],
  72.             'workflow.quotation_status.completed.to_draft' => [
  73.                 ['createSubscriptions'],
  74.                 ['quotationCreatedNotify']
  75.             ],
  76.             'workflow.quotation_status.completed.to_new' => [
  77.                 ['webOrShopNewQuotationNotify'30],
  78.                 ['quotationDataUpdate'20],
  79.                 ['pipeDriveRegister'10],
  80.             ],
  81.             'workflow.quotation_status.completed.to_processing' => [
  82.                 ['setQuotationManager'],
  83.                 ['createManagerSubscriptions']
  84.             ],
  85.             'workflow.quotation_status.completed.to_production' => [
  86.                 ['updatePlannedDeadline']
  87.                 ],
  88.             'workflow.quotation_status.completed.to_delivered' => [
  89.                 ['logDeliveryDate'],
  90.                 ],
  91.             'workflow.quotation_status.completed.to_finished' => [
  92.                 ['removeSubscriptions'],
  93.                 ['updateCustomerOrderCount'],
  94.                 ['updateManufacturerOrderCount'],
  95.                 ],
  96.             'workflow.quotation_status.completed.to_rejected' => [
  97.                 ['quotationInquiriesToDeclined'],
  98.                 ['quotationInvoicesToCanceled'],
  99.                 ['removeSubscriptions']
  100.                 ],
  101.             'workflow.quotation_status.completed.to_deleted' => [
  102.                 ['removeSubscriptions']
  103.             ],
  104.             'workflow.quotation_status.announce' => [
  105.                 ['addLastUpdateTime'],
  106.                 ['logTransition'],
  107.                 ['quotationStatusChangeNotify']
  108.             ],
  109.         ];
  110.     }
  111.     public function toReadyGuard(GuardEvent $event)
  112.     {
  113.         if ( !$this->security->isGranted('ROLE_SALES_MANAGER') ) {
  114.             $event->setBlocked(true);
  115.         }
  116.         if ( !$event->getSubject()->getCustomer() ) {
  117.             $event->setBlocked(true);
  118.         }
  119.     }
  120.     public function canBeDeletedGuard(GuardEvent $event)
  121.     {
  122.         $quotation $event->getSubject();
  123.         if ( !$this->security->isGranted('ROLE_QUOTATION_CAN_DELETE') ) {
  124.             $event->setBlocked(true);
  125.         }
  126.         if ( count($quotation->getPriceInquiries()) > ) {
  127.             $event->setBlocked(true);
  128.         }
  129.     }
  130.     public function inquiriesSentGuard(GuardEvent $event)
  131.     {
  132.         if ( !$this->security->isGranted('ROLE_CAN_CREATE_INQUIRIES') ) {
  133.             $event->setBlocked(true);
  134.         }
  135.         if ( !count($event->getSubject()->getPriceInquiries()) ) {
  136.             $event->setBlocked(true);
  137.         }
  138.     }
  139.     public function offersPartiallyReceivedGuard(GuardEvent $event)
  140.     {
  141.         if ( $event->getSubject()->getPriceInquiries() ) {
  142.             foreach ( $event->getSubject()->getPriceInquiries() as $inquiry ) {
  143.                 if ( $inquiry->getStatus() == PriceInquiry::STATUS_OFFER ) {
  144.                     return;
  145.                 }
  146.             }
  147.         }
  148.         $event->setBlocked(true);
  149.     }
  150.     public function offersReceivedGuard(GuardEvent $event)
  151.     {
  152.         if ( !$this->security->isGranted('ROLE_CAN_CREATE_INQUIRIES') ) {
  153.             $event->setBlocked(true);
  154.         }
  155.         if ( $event->getSubject()->getPriceInquiries() ) {
  156.             foreach ( $event->getSubject()->getPriceInquiries() as $inquiry ) {
  157.                 if ( $inquiry->getStatus() == PriceInquiry::STATUS_OFFER && $inquiry->getOfferVerified() ) {
  158.                     return;
  159.                 }
  160.             }
  161.         }
  162.         $event->setBlocked(true);
  163.     }
  164.     public function toOrderedGuard(Event $event)
  165.     {
  166.         if ( $event->getSubject()->getPriceInquiries() ) {
  167.             foreach ( $event->getSubject()->getPriceInquiries() as $inquiry ) {
  168.                 if ( $inquiry->getStatus() == PriceInquiry::STATUS_ACCEPTED ) {
  169.                     return;
  170.                 }
  171.             }
  172.         }
  173.         $event->setBlocked(true);
  174.     }
  175.     public function toWaitingPaymentGuard(GuardEvent $event)
  176.     {
  177.         if ( $this->security->getUser() && !$this->security->isGranted('ROLE_SALES_MANAGER') ) {
  178.             $event->setBlocked(true);
  179.         }
  180.     }
  181.     public function toAcceptedGuard(GuardEvent $event)
  182.     {
  183.         if (
  184.             $this->security->isGranted('ROLE_SALES_MANAGER')
  185.             ||
  186.             $this->security->isGranted(UserVoter::IS_APP_CUSTOMER$this->security->getUser())
  187.         ) {
  188.             return;
  189.         }
  190.         $event->setBlocked(true);
  191.     }
  192.     public function createSubscriptions(Event $event)
  193.     {
  194.         $this->subscriptionService->generateSubscriptions($event->getSubject(), $event->getSubject()->getCreatedBy());
  195.     }
  196.     public function quotationCreatedNotify(Event $event)
  197.     {
  198.         $this->subscriptionService->proceedEvent(
  199.             SubscriptionEvent::QUOTATION_CREATED_DRAFT,
  200.             $event->getSubject(),
  201.             ['data' => ['uuid' => $event->getSubject()->getUuid()]]
  202.         );
  203.     }
  204.     public function webOrShopNewQuotationNotify(Event $event)
  205.     {
  206.         if (!$event->getSubject()->getCreatedBy() ) {
  207.             $this->subscriptionService->proceedEvent(
  208.                 $event->getSubject()->getIsWebShopRelated() ? SubscriptionEvent::QUOTATION_CREATED_SHOP SubscriptionEvent::QUOTATION_CREATED_WEB,
  209.                 $event->getSubject(),
  210.                 ['data' => ['uuid' => $event->getSubject()->getUuid()]]
  211.             );
  212.         }
  213.     }
  214.     public function quotationDataUpdate(Event $event)
  215.     {
  216.         $event->getSubject()->setDateSubmitted(new \DateTime());
  217.         $event->getSubject()->setOrderNumber($this->quotationRepo->getTodaysIterator());
  218.     }
  219.     public function pipeDriveRegister(Event $event)
  220.     {
  221.         $customer $event->getSubject()->getCustomer();
  222.         if (!$customer || !$customer->getEmail()) {
  223.             return;
  224.         }
  225.         $this->rabbitMQDispatcher->dispatch([
  226.             'data' => [
  227.                 'organization' => $customer->getName(),
  228.                 'name' => $customer->getPersonName() ?? $customer->getName(),
  229.                 'email' => $customer->getEmail(),
  230.                 'phone' => $customer->getPhone(),
  231.                 'order_number' => $event->getSubject()->getOrderNumber(),
  232.             ],
  233.             'action_name' => 'pipeDriveRegister',
  234.             'consumer_name' => 'pipe_drive_consumer'
  235.         ]);
  236.     }
  237.     public function setQuotationManager(Event $event)
  238.     {
  239.         $event->getSubject()->setManager($this->security->getUser());
  240.     }
  241.     public function createManagerSubscriptions(Event $event)
  242.     {
  243.         if ($event->getSubject()->getManager() !== $event->getSubject()->getCreatedBy()) {
  244.             $this->subscriptionService->generateSubscriptions($event->getSubject(), $event->getSubject()->getManager());
  245.         }
  246.     }
  247.     public function updatePlannedDeadline(Event $event)
  248.     {
  249.         if ( $event->getSubject()->getOrderInquiry() ) {
  250.             $date = (new \DateTime())->modify('+' $event->getSubject()->getOrderInquiry()->getFullLeadDays() .' day');
  251.             $event->getSubject()->setPlannedDeadline($date);
  252.         }
  253.     }
  254.     public function logDeliveryDate(Event $event)
  255.     {
  256.         $this->logService->logAction(
  257.             $event->getSubject(),
  258.             'log.quotation.delivery.date',
  259.             $event->getSubject()->getDeliveryDate()->format('Y.m.d')
  260.         );
  261.     }
  262.     public function updateCustomerOrderCount(Event $event)
  263.     {
  264.         if ($customer $event->getSubject()->getCustomer()) {
  265.             $count $customer->getOrderCount();
  266.             $count++;
  267.             $customer->setOrderCount($count);
  268.             $this->em->flush();
  269.         }
  270.     }
  271.     public function updateManufacturerOrderCount(Event $event)
  272.     {
  273.         if ($manufacturer $event->getSubject()->getOrderInquiry()->getManufacturer()) {
  274.             $count $manufacturer->getOrderCount();
  275.             $count++;
  276.             $manufacturer->setOrderCount($count);
  277.             $this->em->flush();
  278.         }
  279.     }
  280.     public function quotationInquiriesToDeclined(Event $event)
  281.     {
  282.         if ( $event->getSubject()->getPriceInquiries() ) {
  283.             foreach ( $event->getSubject()->getPriceInquiries() as $inquiry ) {
  284.                 if ( !in_array($inquiry->getStatus(), [PriceInquiry::STATUS_DECLINEDPriceInquiry::STATUS_REJECTED]) ) {
  285.                     $workflow $this->workflows->get($inquiry);
  286.                     if ( $workflow->can($inquiry'to_declined') ) {
  287.                         $workflow->apply($inquiry'to_declined');
  288.                     }
  289.                 }
  290.             }
  291.         }
  292.     }
  293.     public function quotationInvoicesToCanceled(Event $event)
  294.     {
  295.         if ( $event->getSubject()->getInvoices() ) {
  296.             foreach ( $event->getSubject()->getInvoices() as $invoice ) {
  297.                 if ($invoice->getInvoiceDirection() !== Invoice::INVOICE_DIRECTION_INCOMING){
  298.                     $this->invoiceService->setCanceled($invoice);
  299.                 }
  300.             }
  301.         }
  302.     }
  303.     public function quotationStatusChangeNotify(Event $event)
  304.     {
  305.         $this->subscriptionService->proceedEvent(
  306.             'quotation.transition.' $event->getTransition()->getName(),
  307.             $event->getSubject(),
  308.             ['data' => [
  309.                 'uuid' => $event->getSubject()->getUuid(),
  310.                 'status' => $event->getSubject()->getStatus()
  311.             ]]
  312.         );
  313.     }
  314.     public function removeSubscriptions(Event $event)
  315.     {
  316.         if ($subscriptions $this->subscriptionRepo->getAll([
  317.             ClassUtils::getClass($event->getSubject()) => $event->getSubject()
  318.         ])) {
  319.             $this->subscriptionService->removeSubs($subscriptions);
  320.         }
  321.     }
  322.     public function addLastUpdateTime(Event $event)
  323.     {
  324.         $event->getSubject()->setLastUpdate(new \DateTime());
  325.     }
  326.     public function logTransition(Event $event)
  327.     {
  328.         $this->logService->logAction(
  329.             $event->getSubject(),
  330.             implode(', '$event->getTransition()->getTos())
  331.             // implode(', ', array_keys($event->getMarking()->getPlaces()))
  332.         );
  333.         $this->userLog->log(
  334.             'quotation',
  335.             'status.update.'.$event->getTransition()->getName(),
  336.             $event->getSubject()->getId(),
  337.             'Quotation status update: '.$event->getTransition()->getName(). ' ' $event->getSubject()->getUuid()
  338.         );
  339.     }
  340. }