vendor/store.shopware.com/premsindividualoffer6/src/Storefront/Controller/OfferController.php line 144

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /**
  3.  * PremSoft
  4.  * Copyright © 2020 Premsoft - Sven Mittreiter
  5.  *
  6.  * @copyright  Copyright (c) 2020, premsoft - Sven Mittreiter (http://www.premsoft.de)
  7.  * @author     Sven Mittreiter <info@premsoft.de>
  8.  */
  9. namespace Prems\Plugin\PremsIndividualOffer6\Storefront\Controller;
  10. use Prems\Plugin\PremsIndividualOffer6\Core\Entity\Offer\Aggregate\OfferItem\OfferItemEntity;
  11. use Prems\Plugin\PremsIndividualOffer6\Core\Offer\NotificationService;
  12. use Prems\Plugin\PremsIndividualOffer6\Core\Offer\PdfService;
  13. use Prems\Plugin\PremsIndividualOffer6\Core\Offer\Storefront\OfferService;
  14. use Prems\Plugin\PremsIndividualOffer6\Core\Entity\Offer\OfferDefinition;
  15. use Prems\Plugin\PremsIndividualOffer6\Core\Entity\Offer\OfferEntity;
  16. use Prems\Plugin\PremsIndividualOffer6\Exception\Offer\OfferNotFoundException;
  17. use Prems\Plugin\PremsIndividualOffer6\Core\Offer\Storefront\ConfigService;
  18. use Prems\Plugin\PremsIndividualOffer6\Storefront\Page\Listing\ListingPageLoader;
  19. use Prems\Plugin\PremsIndividualOffer6\Traits;
  20. use Shopware\Core\Checkout\Cart\Cart;
  21. use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
  22. use Shopware\Core\Checkout\Cart\Exception\LineItemNotFoundException;
  23. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  24. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  25. use Shopware\Core\Checkout\Promotion\Cart\Discount\DiscountLineItem;
  26. use Shopware\Core\Content\Product\Exception\ProductNotFoundException;
  27. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  28. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  29. use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
  30. use Shopware\Core\PlatformRequest;
  31. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
  32. use Shopware\Core\System\SalesChannel\SalesChannel\AbstractContextSwitchRoute;
  33. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  34. use Shopware\Storefront\Controller\StorefrontController;
  35. use Symfony\Component\HttpFoundation\JsonResponse;
  36. use Symfony\Component\HttpFoundation\ParameterBag;
  37. use Symfony\Component\HttpFoundation\Request;
  38. use Symfony\Component\HttpFoundation\Response;
  39. use Symfony\Component\HttpFoundation\Session\Session;
  40. use Symfony\Component\Routing\Annotation\Route;
  41. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  42. use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
  43. use Twig\Environment;
  44. use Symfony\Component\HttpFoundation\HeaderUtils;
  45. /**
  46.  * @RouteScope(scopes={"storefront"})
  47.  */
  48. class OfferController extends StorefrontController
  49. {
  50.     use Traits\DocumentCreateResponseTrait;
  51.     /**
  52.      * @var ListingPageLoader
  53.      */
  54.     private $listingPageLoader;
  55.     /**
  56.      * @var OfferService $offerService
  57.      */
  58.     private $offerService;
  59.     /**
  60.      * @var Session $session
  61.      */
  62.     private $session;
  63.     /**
  64.      * @var NotificationService $notificationService
  65.      */
  66.     private $notificationService;
  67.     /**
  68.      * @var ConfigService
  69.      */
  70.     public $configService;
  71.     private PdfService $pdfService;
  72.     /**
  73.      * @var CartService
  74.      */
  75.     private $cartService;
  76.     /**
  77.      * @var AbstractContextSwitchRoute
  78.      */
  79.     private $contextSwitchRoute;
  80.     public function __construct(
  81.         ListingPageLoader $listingPageLoader,
  82.         OfferService $offerService,
  83.         NotificationService $notificationService,
  84.         ConfigService $configService,
  85.         PdfService $pdfService,
  86.         Session $session,
  87.         CartService $cartService,
  88.         AbstractContextSwitchRoute $contextSwitchRoute
  89.     ) {
  90.         $this->listingPageLoader  $listingPageLoader;
  91.         $this->offerService $offerService;
  92.         $this->notificationService $notificationService;
  93.         $this->session $session;
  94.         $this->configService $configService;
  95.         $this->pdfService $pdfService;
  96.         $this->cartService $cartService;
  97.         $this->contextSwitchRoute $contextSwitchRoute;
  98.     }
  99.     /**
  100.      * renders the pdf View
  101.      *
  102.      * @HttpCache()
  103.      * @Route("/offer/renderpdf/{offerId}", name="frontend.PremsIndividualOffer.renderpdf", methods={"POST", "GET"}, defaults={"XmlHttpRequest": false})
  104.      */
  105.     public function renderPdf(Request $requestSalesChannelContext $salesChannelContext): Response
  106.     {
  107.         $this->denyAccessUnlessLoggedIn();
  108.         $offerId $request->attributes->get('offerId');
  109.         $pdfFile $this->pdfService->createPdfForOffer($offerId$salesChannelContext);
  110.         $download $request->query->getBoolean('download'false);
  111.         return $this->createResponse($pdfFile->getFileName(), $pdfFile->getBlobContent(), $download'application/pdf');
  112.     }
  113.     /**
  114.      * Show all offers of a customer. If not logged in then redirected to login page
  115.      * @Route(
  116.      *     "/account/offer",
  117.      *     name="frontend.PremsIndividualOffer.index",
  118.      *     options={"seo"="false"},
  119.      *     methods={"GET"},
  120.      *     defaults={"XmlHttpRequest"=true}
  121.      * )
  122.      *
  123.      * @param SalesChannelContext $context
  124.      * @param Request $request
  125.      *
  126.      * @return Response
  127.      */
  128.     public function offerOverview(SalesChannelContext $contextRequest $request): Response
  129.     {
  130.         $this->denyAccessUnlessLoggedIn();
  131.         $page $this->listingPageLoader->load($request$context);
  132.         $offerSettings $this->configService->getConfig($context);
  133.         $openRequestCount $this->offerService->getOpenRequestCount($context->getCustomer(), $context->getContext());
  134.         $receivedCount $this->offerService->getReceivedCount($context->getCustomer(), $context->getContext());
  135.         $orderedCount $this->offerService->getOrderedCount($context->getCustomer(), $context->getContext());
  136.         $declinedCount $this->offerService->getDeclinedCount($context->getCustomer(), $context->getContext());
  137.         $offerId null;
  138.         if ($this->session->has('PremsIndividualOfferId')) {
  139.             $offerId $this->session->get('PremsIndividualOfferId');
  140.             $this->session->remove('PremsIndividualOfferId');
  141.         }
  142.         return $this->renderStorefront('@PremsIndividualOffer6/storefront/page/individual_offer/index.html.twig', [
  143.             'page' => $page,
  144.             'openRequestCount' => $openRequestCount,
  145.             'receivedCount' => $receivedCount,
  146.             'orderedCount' => $orderedCount,
  147.             'declinedCount' => $declinedCount,
  148.             'offerSettings' => $offerSettings,
  149.             'offerId' => $offerId,
  150.             'flashBags' => $this->session->getFlashBag()->peekAll(),
  151.         ]);
  152.     }
  153.     /**
  154.      * @Route(
  155.      *   "/widgets/account/offer/detail/{id}",
  156.      *   name="frontend.PremsIndividualOffer.ajaxOfferDetail",
  157.      *   options={"seo"="false"},
  158.      *   methods={"GET"},
  159.      *   defaults={"XmlHttpRequest"=true})
  160.      *
  161.      * @param SalesChannelContext $context
  162.      * @param Request $request
  163.      */
  164.     public function ajaxOfferDetail(SalesChannelContext $contextRequest $request)
  165.     {
  166.         $this->denyAccessUnlessLoggedIn();
  167.         $offerSettings $this->configService->getConfig($context);
  168.         $offerId = (string) $request->get('id');
  169.         if ($offerId === '') {
  170.             throw new MissingRequestParameterException('id');
  171.         }
  172.         $offer $this->offerService->getOfferById($offerId$context->getContext(), $context->getCustomer());
  173.         if (!$offer) {
  174.             throw new OfferNotFoundException("Offer $offerId not found");
  175.         }
  176.         $customerId $context->getCustomer()->getId();
  177.         $items $this->offerService->getItemsFromOffer($offerId$customerId$context);
  178.         return $this->renderStorefront('@PremsIndividualOffer6/storefront/page/individual_offer/offer-detail-list.html.twig',
  179.             [
  180.                 'offerDetails' => $items,
  181.                 'offerId' => $offerId,
  182.                 'offerSettings' => $offerSettings,
  183.                 'offer' => $offer,
  184.             ]);
  185.     }
  186.     /**
  187.      * Cancel the offer mode
  188.      * @Route(
  189.      *     "/individual_offer/cancel_offer_mode",
  190.      *     name="frontend.PremsIndividualOffer.cancelOfferMode",
  191.      *     options={"seo"="false"},
  192.      *     methods={"POST"}
  193.      * )
  194.      *
  195.      * @param SalesChannelContext $context
  196.      * @param Request $request
  197.      *
  198.      * @return Response
  199.      */
  200.     public function cancelOfferMode(SalesChannelContext $contextRequest $request): Response
  201.     {
  202.         $this->offerService->cancelOfferMode($context);
  203.         $this->addFlash('info'$this->trans('prems-individual-offer.status_messages.cancel_offer_mode'));
  204.         return $this->redirectToRoute('frontend.PremsIndividualOffer.index');
  205.     }
  206.     /**
  207.      * Cancel the offer mode
  208.      * @Route(
  209.      *     "/individual_offer/send-message",
  210.      *     name="frontend.PremsIndividualOffer.sendMessage",
  211.      *     options={"seo"="false"},
  212.      *     methods={"POST"}
  213.      * )
  214.      *
  215.      * @param SalesChannelContext $context
  216.      * @param Request $request
  217.      *
  218.      * @return Response
  219.      */
  220.     public function sendMessage(SalesChannelContext $contextRequest $request): Response
  221.     {
  222.         $customer $context->getCustomer();
  223.         $message $request->request->get('message''');
  224.         $offerId $request->request->get('offerId');
  225.         $offer $this->offerService->getOfferById($offerId$context->getContext(), $customer);
  226.         if (!empty($customer) && $offer && $message) {
  227.             $bag = new ParameterBag([
  228.                 'message' => $message,
  229.                 'customerSign' => $request->request->get('customerSign'),
  230.             ]);
  231.             $this->notificationService->customerGeneralMessageToAdmin($context$offer$bag);
  232.         } else {
  233.             return new JsonResponse([
  234.                 'status' => 0,
  235.             ]);
  236.         }
  237.         return new JsonResponse([
  238.             'status' => 1,
  239.             'message' => $this->trans('prems-individual-offer.messages.message_send_successfully')
  240.         ]);
  241.     }
  242.     /**
  243.      * Request for an offer
  244.      * @Route(
  245.      *     "/individual_offer/request",
  246.      *     name="frontend.PremsIndividualOffer.request",
  247.      *     methods={"POST","GET"}
  248.      * )
  249.      *
  250.      * @param SalesChannelContext $context
  251.      * @param Request $request
  252.      *
  253.      * @return Response
  254.      */
  255.     public function request(SalesChannelContext $contextRequest $request): Response
  256.     {
  257.         $this->denyAccessUnlessLoggedIn();
  258.         $customer $context->getCustomer();
  259.         if ($this->offerService->isOfferRequestAllowed($context)) {
  260.             $customerGroup $context->getCurrentCustomerGroup();
  261.             if (!$customerGroup) {
  262.                 $customerGroup $context->getFallbackCustomerGroup();
  263.             }
  264.             $offerSettings $this->configService->getConfig($context);
  265.             $event $this->offerService->createOfferRequest($customer$customerGroup$context);
  266.             $nested $event->getEventByEntityName(OfferDefinition::ENTITY_NAME);
  267.             if ($nested) {
  268.                 foreach ($nested->getIds() as $id) {
  269.                     $offer $this->offerService->getOfferById($id$context->getContext());
  270.                     $items $this->offerService->getItemsFromOffer($offer->getId(), $customer->getId(), $context);
  271.                     /** @var OfferItemEntity $item */
  272.                     foreach($items as $item) {
  273.                         //dirty hack, since the twig method is not available in the twig renderer here
  274.                         $item->decodedLineItem unserialize(base64_decode($item->getLineItem()), [LineItem::class, DiscountLineItem::class]);
  275.                     }
  276.                     $this->notificationService->customerCreatedOfferRequest($context$offer$items);
  277.                     $this->session->set('PremsIndividualOfferId'$id);
  278.                 }
  279.             }
  280.             if ($offerSettings->isClearBasketAfterOfferRequest()) {
  281.                 // Empty cart
  282.                 $cart $this->cartService->getCart($context->getToken(), $context);
  283.                 $items $cart->getLineItems();
  284.                 foreach($items as $item) {
  285.                     $this->cartService->remove($cart$item->getId(), $context);
  286.                 }
  287.             }
  288.             $this->addFlash('success'$this->trans('prems-individual-offer.status_messages.offer_request_created', ['%offerNumber%' => $offer->getOfferNumber()]));
  289.             return $this->redirectToRoute('frontend.PremsIndividualOffer.index');
  290.         } else {
  291.             $this->addFlash('error'$this->trans('prems-individual-offer.status_messages.not_allowed_to_create_offer_request'));
  292.             return $this->redirectToRoute('frontend.checkout.cart.page');
  293.         }
  294.     }
  295.     /**
  296.      * @Route("/individual_offer/line-item/add",
  297.      *     name="frontend.PremsIndividualOffer.line-item.add",
  298.      *     methods={"POST","GET"},
  299.      *     defaults={"XmlHttpRequest"=true})
  300.      *
  301.      * requires the provided items in the following form
  302.      * 'lineItems' => [
  303.      *     'anyKey' => [
  304.      *         'id' => 'someKey'
  305.      *         'quantity' => 2,
  306.      *         'type' => 'someType'
  307.      *     ],
  308.      *     'randomKey' => [
  309.      *         'id' => 'otherKey'
  310.      *         'quantity' => 2,
  311.      *         'type' => 'otherType'
  312.      *     ]
  313.      * ]
  314.      *
  315.      * @param Cart $cart
  316.      * @param RequestDataBag $requestDataBag
  317.      * @param Request $request
  318.      * @param SalesChannelContext $context
  319.      * @return Response
  320.      */
  321.     public function addLineItems(Cart $cartRequestDataBag $requestDataBagRequest $requestSalesChannelContext $context): Response
  322.     {
  323.         // Not allowed for guests
  324.         if (!($context && $context->getCustomer() && !$context->getCustomer()->getGuest())) {
  325.             $this->setPriceRequestDataBeforeLogin($requestDataBag);
  326.         }
  327.         $this->denyAccessUnlessLoggedIn();
  328.         $this->removeCartLineItems($cart$context);
  329.         /** @var RequestDataBag|null $lineItems */
  330.         $lineItems $requestDataBag->get('lineItems');
  331.         if (!$lineItems && !($lineItems=$this->getPriceRequestDataAfterLogin())) {
  332.             throw new MissingRequestParameterException('lineItems');
  333.         }
  334.         $count 0;
  335.         try {
  336.             $items = [];
  337.             /** @var RequestDataBag $lineItemData */
  338.             foreach ($lineItems as $lineItemData) {
  339.                 $lineItem = new LineItem(
  340.                     $lineItemData->getAlnum('id'),
  341.                     $lineItemData->getAlnum('type'),
  342.                     $lineItemData->get('referencedId'),
  343.                     $lineItemData->getInt('quantity'1)
  344.                 );
  345.                 $lineItem->setStackable($lineItemData->getBoolean('stackable'true));
  346.                 $lineItem->setRemovable($lineItemData->getBoolean('removable'true));
  347.                 $count += $lineItem->getQuantity();
  348.                 $items[] = $lineItem;
  349.             }
  350.             $cart $this->offerService->addCartItems($cart$items$context);
  351.             if ($cart->getErrors()->count() <= 0) {
  352.                 // Adding products to the offer
  353.                 $customer $context->getCustomer();
  354.                 if ($this->offerService->isOfferRequestAllowed($context)) {
  355.                     $customerGroup $context->getCurrentCustomerGroup();
  356.                     if (!$customerGroup) {
  357.                         $customerGroup $context->getFallbackCustomerGroup();
  358.                     }
  359.                     $event $this->offerService->createOfferRequest($customer$customerGroup$context);
  360.                     $nested $event->getEventByEntityName(OfferDefinition::ENTITY_NAME);
  361.                     if ($nested) {
  362.                         foreach ($nested->getIds() as $id) {
  363.                             $offer $this->offerService->getOfferById($id$context->getContext());
  364.                             $items $this->offerService->getItemsFromOffer($offer->getId(), $customer->getId(), $context);
  365.                             /** @var OfferItemEntity $item */
  366.                             foreach($items as $item) {
  367.                                 //dirty hack, since the twig method is not available in the twig renderer here
  368.                                 $item->decodedLineItem unserialize(base64_decode($item->getLineItem()), [LineItem::class, DiscountLineItem::class]);
  369.                             }
  370.                             $this->notificationService->customerCreatedOfferRequest($context$offer$items);
  371.                             $this->session->set('PremsIndividualOfferId'$id);
  372.                         }
  373.                     }
  374.                     /** @var OfferItemEntity $lineItem */
  375.                     foreach ($items as $lineItem) {
  376.                         // Deleting products form the cart after making offer
  377.                         $id $lineItem->getProductId();
  378.                         if (!$cart->has($id)) {
  379.                             throw new LineItemNotFoundException($id);
  380.                         }
  381.                         $cart $this->offerService->removeCartItem($cart$id$context);
  382.                     }
  383.                     $this->restoreCartLineItems($cart$context);
  384.                     $this->addFlash('success'$this->trans('prems-individual-offer.status_messages.offer_request_created', ['%offerNumber%' => $offer->getOfferNumber()]));
  385.                     return $this->redirectToRoute('frontend.PremsIndividualOffer.index');
  386.                 } else {
  387.                     $this->addFlash('error'$this->trans('prems-individual-offer.status_messages.not_allowed_to_create_offer_request'));
  388.                     return $this->createActionResponse($request);
  389.                 }
  390.             }
  391.         } catch (ProductNotFoundException $exception) {
  392.             $this->addFlash('danger'$this->trans('error.addToCartError'));
  393.         }
  394.         return $this->createActionResponse($request);
  395.     }
  396.     /**
  397.      * Accept an offer and add to basket
  398.      * @Route(
  399.      *     "/individual_offer/order",
  400.      *     name="frontend.PremsIndividualOffer.order",
  401.      *     methods={"GET"}
  402.      * )
  403.      *
  404.      * @param SalesChannelContext $context
  405.      * @param Request $request
  406.      *
  407.      * @return Response
  408.      */
  409.     public function order(SalesChannelContext $contextRequest $request): Response
  410.     {
  411.         $this->denyAccessUnlessLoggedIn();
  412.         $offerId $request->get('offerId');
  413.         $customer $context->getCustomer();
  414.         if (!$offerId) {
  415.             throw new \Exception('No offer id specified');
  416.         }
  417.         /** @var OfferEntity $offer */
  418.         $offer $this->offerService->getOfferById($offerId$context->getContext(), $customer);
  419.         if (!$offer || !$this->offerService->hasAccessToOffer($offer$customer) || !$this->offerService->isOfferOrderable($offer)) {
  420.             $this->addFlash('danger'$this->trans('prems-individual-offer.status_messages.no_access_to_offer'));
  421.             return $this->redirectToRoute('frontend.PremsIndividualOffer.index');
  422.         }
  423.         // If offer mode is activated no second offer order is allowed
  424.         if ($this->offerService->getOfferMode($context)) {
  425.             $this->addFlash('danger'$this->trans('prems-individual-offer.status_messages.no_double_order_offer_mode_active'));
  426.             return $this->redirectToRoute('frontend.PremsIndividualOffer.index');
  427.         }
  428.         if ($offer->getShippingMethodId()) {
  429.             $requestDataBag = new RequestDataBag([SalesChannelContextService::SHIPPING_METHOD_ID => $offer->getShippingMethodId()]);
  430.             try {
  431.                 $this->contextSwitchRoute->switchContext($requestDataBag$context);
  432.             } catch (ConstraintViolationException $exception) {
  433.                 $this->addFlash('error'$this->trans('prems-individual-offer.status_messages.error_creating_offer_cart'));
  434.                 return $this->redirectToRoute('frontend.PremsIndividualOffer.index');
  435.             }
  436.         }
  437.         $this->offerService->activateOfferMode($context$offer->getId());
  438.         $this->offerService->addOfferToBasket($offer$context);
  439.         return $this->redirectToRoute('frontend.checkout.cart.page');
  440.     }
  441.     /**
  442.      * Decline an offer
  443.      * @Route(
  444.      *     "/individual_offer/decline",
  445.      *     name="frontend.PremsIndividualOffer.decline",
  446.      *     methods={"GET"}
  447.      * )
  448.      *
  449.      * @param SalesChannelContext $context
  450.      * @param Request $request
  451.      * @return Response
  452.      */
  453.     public function decline(SalesChannelContext $contextRequest $request): Response
  454.     {
  455.         $this->denyAccessUnlessLoggedIn();
  456.         $offerId $request->get('offerId');
  457.         $customer $context->getCustomer();
  458.         $offer $this->offerService->getOfferById($offerId$context->getContext(), $customer);
  459.         if (!$offerId) {
  460.             throw new \Exception('No offer id specified');
  461.         }
  462.         if (!$offer || !$this->offerService->hasAccessToOffer($offer$customer) || !$this->offerService->isOfferDeclineable($offer)) {
  463.             $this->addFlash('error'$this->trans('prems-individual-offer.status_messages.no_access_to_offer'));
  464.             return $this->redirectToRoute('frontend.PremsIndividualOffer.index');
  465.         }
  466.         $this->offerService->declineOffer($offer$context->getContext());
  467.         $this->notificationService->customerDeclinedOffer($context$offer);
  468.         // If current offer is in offer mode (basket) then remove it
  469.         if ($this->offerService->getOfferMode($context) == $offerId) {
  470.             $this->offerService->cancelOfferMode($context);
  471.         }
  472.         $this->addFlash('success'$this->trans('prems-individual-offer.status_messages.declined_offer_successfully'));
  473.         return $this->redirectToRoute('frontend.PremsIndividualOffer.index');
  474.     }
  475.     /**
  476.      * @param Cart $cart
  477.      * @param SalesChannelContext $context
  478.      */
  479.     private function removeCartLineItems(Cart $cartSalesChannelContext $context)
  480.     {
  481.         $this->session->remove('premsIndividualOffer.LineItems');
  482.         $cartLineItems = [];
  483.         // Remove Line Items from cart before adding new one
  484.         foreach ($cart->getLineItems() as $lItem) {
  485.             $lId $lItem->getId();
  486.             $cartLineItems [$lId] = [
  487.                 'id' => $lItem->getId(),
  488.                 'type' => $lItem->getType(),
  489.                 'referencedId' => $lItem->getReferencedId(),
  490.                 'quantity' => $lItem->getQuantity(),
  491.                 'stackable' => $lItem->isStackable(),
  492.                 'removable' => $lItem->isRemovable(),
  493.             ];
  494.             if (!$cart->has($lId)) {
  495.                 throw new LineItemNotFoundException($lId);
  496.             }
  497.             if ($lItem->isRemovable()) {
  498.                 $this->offerService->removeCartItem($cart$lId$context);
  499.             }
  500.         }
  501.         // Add Line items to session to restore them after offer request
  502.         $this->session->set('premsIndividualOffer.LineItems'$cartLineItems);
  503.     }
  504.     /**
  505.      * @param Cart $cart
  506.      * @param SalesChannelContext $context
  507.      */
  508.     private function restoreCartLineItems(Cart $cartSalesChannelContext $context)
  509.     {
  510.         $lineItemsList $this->session->get('premsIndividualOffer.LineItems');
  511.         $items = [];
  512.         foreach ($lineItemsList as $item) {
  513.             $lineItem = new LineItem($item['id'], $item['type'], $item['referencedId'], $item['quantity']);
  514.             $lineItem->setStackable($item['stackable']);
  515.             $lineItem->setRemovable($item['removable']);
  516.             $items[] = $lineItem;
  517.         }
  518.         $this->offerService->addCartItems($cart$items$context);
  519.         $this->session->remove('premsIndividualOffer.LineItems');
  520.     }
  521.     /**
  522.      * @param RequestDataBag $requestDataBag
  523.      */
  524.     private function setPriceRequestDataBeforeLogin(RequestDataBag $requestDataBag)
  525.     {
  526.         $this->session->remove('premsIndividualOffer.storedPriceRequestData');
  527.         /** @var RequestDataBag|null $lineItems */
  528.         $lineItems $requestDataBag->get('lineItems');
  529.         if (!$lineItems) {
  530.             throw new MissingRequestParameterException('lineItems');
  531.         }
  532.         $this->session->set('premsIndividualOffer.storedPriceRequestData'$lineItems);
  533.     }
  534.     /**
  535.      * @return mixed
  536.      */
  537.     private function getPriceRequestDataAfterLogin()
  538.     {
  539.         return $this->session->get('premsIndividualOffer.storedPriceRequestData');
  540.     }
  541.     /**
  542.      * @throws CustomerNotLoggedInException
  543.      */
  544.     protected function denyAccessUnlessLoggedIn(bool $allowGuest false): void
  545.     {
  546.         /** @var RequestStack $requestStack */
  547.         $requestStack $this->get('request_stack');
  548.         $request $requestStack->getCurrentRequest();
  549.         if (!$request) {
  550.             throw new CustomerNotLoggedInException();
  551.         }
  552.         /** @var SalesChannelContext|null $context */
  553.         $context $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  554.         if (
  555.             $context
  556.             && $context->getCustomer()
  557.             && (
  558.                 $allowGuest === true
  559.                 || $context->getCustomer()->getGuest() === false
  560.             )
  561.         ) {
  562.             return;
  563.         }
  564.         throw new CustomerNotLoggedInException();
  565.     }
  566. }