- <?php
- namespace Kaylo\Management\Subscriber;
- use Kaylo\Management\Service\WorkshopCart\WorkshopCartLineItemHandler;
- use NetzpEvents6\Components\EventsHelper;
- use NetzpEvents6\Components\SlotStruct;
- use NetzpEvents6\Core\Content\Participant\ParticipantEntity;
- use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
- use Shopware\Core\Checkout\Cart\Event\BeforeLineItemQuantityChangedEvent;
- use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
- use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
- use Shopware\Core\Checkout\Document\DocumentConfigurationFactory;
- use Shopware\Core\Checkout\Document\DocumentService;
- use Shopware\Core\Checkout\Document\FileGenerator\FileTypes;
- use Shopware\Core\Checkout\Order\Event\OrderStateMachineStateChangeEvent;
- use Shopware\Core\Defaults;
- use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
- use Shopware\Core\Framework\Uuid\Uuid;
- use Shopware\Core\System\NumberRange\ValueGenerator\NumberRangeValueGeneratorInterface;
- use Shopware\Core\System\SystemConfig\SystemConfigService;
- use Shopware\Storefront\Page\Account\Order\AccountOrderPageLoadedEvent;
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Symfony\Component\EventDispatcher\EventSubscriberInterface;
- use Symfony\Component\HttpFoundation\RequestStack;
- class WorkshopCheckoutSubscriber implements EventSubscriberInterface {
-     private $container;
-     private $config;
-     private $requestStack;
-     private $helper;
-     private $withoutParticipants;
-     private $documentService;
-     private $numberRangeValueGenerator;
-     public function __construct(
-         ContainerInterface                 $container,
-         SystemConfigService                $config,
-         RequestStack                       $requestStack,
-         EventsHelper                       $helper,
-         DocumentService                    $documentService,
-         NumberRangeValueGeneratorInterface $numberRangeValueGenerator
-     ) {
-         $this->container                 = $container;
-         $this->config                    = $config;
-         $this->requestStack              = $requestStack;
-         $this->helper                    = $helper;
-         $this->documentService           = $documentService;
-         $this->numberRangeValueGenerator = $numberRangeValueGenerator;
-         $pluginConfig              = $this->config->get('NetzpEvents6.config');
-         $this->withoutParticipants = (bool)$pluginConfig['anonymous'];
-     }
-     public static function getSubscribedEvents() {
-         return [
-             BeforeLineItemAddedEvent::class => 'onLineItemAdded',
-             BeforeLineItemQuantityChangedEvent::class => 'onLineItemUpdated',
-             CartConvertedEvent::class => 'onCartConverted',
-             CheckoutOrderPlacedEvent::class => 'onOrderPlaced',
-             AccountOrderPageLoadedEvent::class => 'onOrderLoaded',
-             'state_enter.order.state.cancelled' => 'orderStateCanceled',
-         ];
-     }
-     public function onCartConverted(CartConvertedEvent $event) {
-         $cart      = $event->getCart();
-         $lineItems = $cart->getLineItems();
-         foreach ($lineItems as $lineItem) {
-             if ($lineItem->getType() !== WorkshopCartLineItemHandler::TYPE) {
-                 return;
-             }
-             foreach ($lineItem->getChildren() as $childLineItem) {
-                 if ($childLineItem->hasPayloadValue('netzp_event')) {
-                     $this->helper->processEvent($childLineItem, $event->getContext());
-                 }
-             }
-         }
-     }
-     public function onLineItemAdded(BeforeLineItemAddedEvent $event) {
-         $lineItem = $event->getLineItem();
-         if ($lineItem->getType() === WorkshopCartLineItemHandler::TYPE) {
-             foreach ($lineItem->getChildren() as $childLineItem) {
-                 $eventId  = $childLineItem->getPayloadValue('netzpEventId');
-                 $repo     = $this->container->get('s_plugin_netzp_events_slots.repository');
-                 $criteria = new Criteria([ $eventId ]);
-                 $criteria->addAssociation('event');
-                 $netzpEventSlot = $repo->search($criteria, $event->getContext())->getEntities()->first();
-                 if ($netzpEventSlot) {
-                     $dateFrom  = $netzpEventSlot->getFrom() ?
-                         $netzpEventSlot->getFrom()->format(\DateTimeInterface::ATOM) :
-                         '';
-                     $dateUntil = $netzpEventSlot->getUntil() ?
-                         $netzpEventSlot->getUntil()->format(\DateTimeInterface::ATOM) :
-                         '';
-                     $slot = new SlotStruct();
-                     $slot->setId($netzpEventSlot->getId());
-                     $slot->setTitle($netzpEventSlot->getEvent()->getTranslated()['title']);
-                     $slot->setLocation($netzpEventSlot->getTranslated()['location']);
-                     $slot->setAddress($netzpEventSlot->getTranslated()['address']);
-                     $slot->setFrom($dateFrom);
-                     $slot->setUntil($dateUntil);
-                     $slot->setAvailable($netzpEventSlot->getTicketsAvailable() - $netzpEventSlot->getTicketsBooked());
-                     if ($this->withoutParticipants) {
-                         $participants    = [];
-                         $participantsIds = [];
-                         for ($i = 1; $i <= $lineItem->getQuantity(); $i++) {
-                             $participants[$i]    = '(' . $i . ')';
-                             $participantsIds[$i] = Uuid::randomHex();
-                         }
-                         $slot->setParticipants($participants);
-                         $slot->setParticipantsIds($participantsIds);
-                     }
-                     $childLineItem->setPayloadValue('netzp_event', $slot->getVars());
-                 }
-             }
-         }
-     }
-     public function onLineItemUpdated(BeforeLineItemQuantityChangedEvent $event) {
-         $lineItem = $event->getLineItem();
-         if ($lineItem->getType() !== WorkshopCartLineItemHandler::TYPE) {
-             return;
-         }
-         foreach ($lineItem->getChildren() as $childLineItem) {
-             if (!$childLineItem->hasPayloadValue('netzp_event')) {
-                 continue;
-             }
-             if ($this->withoutParticipants) {
-                 $participants    = [];
-                 $participantsIds = [];
-                 for ($i = 1; $i <= $childLineItem->getQuantity(); $i++) {
-                     $participants[$i]    = '(' . $i . ')';
-                     $participantsIds[$i] = Uuid::randomHex();
-                 }
-                 $payload                    = $childLineItem->getPayloadValue('netzp_event');
-                 $payload['participants']    = $participants;
-                 $payload['participantsIds'] = $participantsIds;
-                 $childLineItem->setPayloadValue('netzp_event', $payload);
-             }
-         }
-     }
-     public function onOrderLoaded(AccountOrderPageLoadedEvent $event) {
-     }
-     public function onOrderPlaced(CheckoutOrderPlacedEvent $event) {
-         $this->processOrder($event);
-     }
-     public function orderStateCanceled(OrderStateMachineStateChangeEvent $event) {
-         $repoSlots        = $this->container->get('s_plugin_netzp_events_slots.repository');
-         $repoParticipants = $this->container->get('s_plugin_netzp_events_participants.repository');
-         $context   = $event->getContext();
-         $lineItems = $event->getOrder()->getLineItems();
-         foreach ($lineItems as $lineItem) {
-             if ($lineItem->getType() !== WorkshopCartLineItemHandler::TYPE) {
-                 continue;
-             }
-             foreach ($lineItem->getChildren() as $childLineItem) {
-                 $payload = $childLineItem->getPayload();
-                 if (array_key_exists('netzp_event', $payload)) {
-                     $ticket = $payload['netzp_event'];
-                     $criteria = new Criteria([ $ticket['id'] ]);
-                     $criteria->addAssociations([ 'event', 'participants', 'event.product' ]);
-                     $slot = $repoSlots->search($criteria, $context)->getEntities()->first();
-                     $numberOfParticipants = count($ticket['participants']);
-                     $newTicketsBooked     = $slot->getTicketsBooked() - $numberOfParticipants;
-                     $repoSlots->update([
-                         [
-                             'id' => $slot->getId(),
-                             'ticketsBooked' => $newTicketsBooked
-                         ]
-                     ], $context);
-                     $this->helper->invalidateProductCache($slot->getEvent()->getProductid());
-                     $this->helper->invalidateEventListing();
-                     foreach ($ticket['participants'] as $participantNo => $participant) {
-                         $participantId = $ticket['participantsIds'][$participantNo];
-                         $repoParticipants->update([
-                             [
-                                 'id' => $participantId,
-                                 'status' => ParticipantEntity::STATUS_CANCELED
-                             ]
-                         ], $context);
-                     }
-                 }
-             }
-         }
-     }
-     public function processOrder(CheckoutOrderPlacedEvent $event) {
-         $order   = $event->getOrder();
-         $context = $event->getContext();
-         $orderId = $order->getId();
-         $pluginConfig      = $this->config->get('NetzpEvents6.config', $event->getSalesChannelId());
-         $repo              = $this->container->get('s_plugin_netzp_events_slots.repository');
-         $repoParticipants  = $this->container->get('s_plugin_netzp_events_participants.repository');
-         $lineItems         = $order->getLineItems();
-         $tickets           = [];
-         $firstTicketNumber = '';
-         $n                 = 0;
-         foreach ($lineItems as $lineItem) {
-             if ($lineItem->getType() !== WorkshopCartLineItemHandler::CHILD_PRODUCT_TYPE) {
-                 continue;
-             }
-             $payload      = $lineItem->getPayload();
-             $productLabel = $lineItem->getLabel();
-             if (array_key_exists('netzp_event', $payload)) {
-                 $ticket = $payload['netzp_event'];
-                 $criteria = new Criteria([ $ticket['id'] ]);
-                 $criteria->addAssociations([ 'event', 'participants', 'event.product' ]);
-                 $slot = $repo->search($criteria, $context)->getEntities()->first();
-                 foreach ($ticket['participants'] as $index => $participant) {
-                     $participantId = $ticket['participantsIds'][$index];
-                     $ticketNumber = '';
-                     if ($pluginConfig['createpdf']) {
-                         $ticketNumber = $this->numberRangeValueGenerator->getValue(
-                             'event_ticket',
-                             $context,
-                             $event->getSalesChannelId()
-                         );
-                         if ($n === 0) {
-                             $firstTicketNumber = $ticketNumber;
-                         }
-                         $tickets[] = [
-                             'participant' => $participant,
-                             'number' => $ticketNumber,
-                             'slot' => $slot,
-                             'product' => $productLabel
-                         ];
-                     }
-                     $repoParticipants->update([
-                         [
-                             'id' => $participantId,
-                             'ticketNumber' => $ticketNumber,
-                             'orderId' => $orderId
-                         ]
-                     ], $context);
-                     $n++;
-                 }
-             }
-         }
-         if ($pluginConfig['createpdf'] && $firstTicketNumber) {
-             $repoAddress     = $this->container->get('order_address.repository');
-             $criteriaAddress = new Criteria([ $order->getBillingAddressId() ]);
-             $billingAddress  = $repoAddress->search($criteriaAddress, $context)->getEntities()->first();
-             $pluginConfig    = $this->config->get('NetzpEvents6.config');
-             $config = DocumentConfigurationFactory::createConfiguration([
-                 'tickets' => $tickets,
-                 'documentDate' => (new \DateTime())->format(Defaults::STORAGE_DATE_TIME_FORMAT),
-                 'documentNumber' => $firstTicketNumber,
-                 'billingAddress' => $billingAddress,
-                 'withoutParticipants' => (bool)$pluginConfig['anonymous']
-             ]);
-             $doc = $this->documentService->create(
-                 $orderId, 'event_ticket', FileTypes::PDF, $config, $context, null, false
-             );
-             // for testing document generation only
-             /*
-             echo $doc->getDeepLinkCode() . " - ";
-             echo "<a href='/api/v3/_action/document/" . $doc->getId() . "/" . $doc->getDeepLinkCode() . "' target='_blank'>Download</a>";
-             die;
-             */
-         }
-     }
- }
-