src/Controller/Main/CartController.php line 89

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Main;
  3. use App\Entity\Main\BankTransfer;
  4. use App\Entity\Main\CardPayment;
  5. use App\Entity\Main\Cart;
  6. use App\Entity\Main\CartAction;
  7. use App\Entity\Main\CartAddress;
  8. use App\Entity\Main\CartCreditNote;
  9. use App\Entity\Main\CodeHtml3DSLog;
  10. use App\Entity\Main\DiscountCode;
  11. use App\Entity\Main\ElectronicProductShipping;
  12. use App\Entity\Main\Pack;
  13. use App\Entity\Main\PackTemplate;
  14. use App\Entity\Main\PaymentToken;
  15. use App\Entity\Main\PaypalPayment;
  16. use App\Entity\Main\Purchase;
  17. use App\Entity\Main\SiteABTest;
  18. use App\Entity\Main\SitePackTemplate;
  19. use App\Entity\Main\Transaction;
  20. use App\Entity\Main\UpsellCart;
  21. use App\Entity\Main\User;
  22. use App\Entity\Main\UserAddress;
  23. use App\Entity\Main\UserCreditNote;
  24. use App\Entity\Main\UserPayment;
  25. use App\Entity\Main\UserSettings;
  26. use App\Events\Main\Cart\CartCreditNoteUsedEvent;
  27. use App\Events\Main\Pack\AddedNonEligiblePackEvent;
  28. use App\Events\Main\Payment\PaymentErrorEvent;
  29. use App\Events\Main\Payment\PaymentSwap3DSEvent;
  30. use App\EventSubscribers\Main\CartSubscriber;
  31. use App\EventSubscribers\Main\PackSubscriber;
  32. use App\EventSubscribers\Main\PaymentSubscriber;
  33. use App\Exceptions\Main\Cart\CartAlreadyPaidException;
  34. use App\Services\CartManager;
  35. use App\Services\EmailManager;
  36. use App\Services\PackManager;
  37. use App\Services\TrackingManager;
  38. use App\Form\Main\BankTransferType;
  39. use App\Form\Main\PaypalPaymentType;
  40. use App\Form\Main\UserAddressType;
  41. use App\Form\Main\UserPaymentType;
  42. use App\Services\ABTestManager;
  43. use App\Services\CartSwitchManager;
  44. use App\Services\DeliveryProvidersManager;
  45. use App\Services\FacebookApiEventsManager;
  46. use App\Services\GeoIPManager;
  47. use App\Services\SiteManager;
  48. use App\Services\TranslationManager;
  49. use App\Services\UserAddressManager;
  50. use App\Tools\ConditionalPacks\FailedPackCondition;
  51. use App\Tools\Forms\FormErrorsResolver;
  52. use App\Tools\ShortId;
  53. use Doctrine\ORM\EntityManagerInterface;
  54. use Exception;
  55. use JMS\Serializer\SerializerInterface;
  56. use Psr\Log\LoggerInterface;
  57. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  58. use Symfony\Component\Asset\Packages;
  59. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  60. use Symfony\Component\Form\FormError;
  61. use Symfony\Component\HttpFoundation\JsonResponse;
  62. use Symfony\Component\HttpFoundation\RedirectResponse;
  63. use Symfony\Component\HttpFoundation\Request;
  64. use Symfony\Component\HttpFoundation\Response;
  65. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  66. use Symfony\Component\Routing\Annotation\Route;
  67. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  68. use Symfony\Contracts\Translation\TranslatorInterface;
  69. use Throwable;
  70. /**
  71.  * @Route(
  72.  *     condition="not (context.getHost() matches '%coaching_domain.host.regexp%')"
  73.  * )
  74.  */
  75. class CartController extends AbstractController
  76. {
  77.     use BrulafineControllerTrait;
  78.     public const UPSELL_PURCHASE_SUCCESS "up_pur_ok";
  79.     /**
  80.      * @Route("/cart/", name="brulafine_cart_start", methods={"GET"})
  81.      * @param Request $request
  82.      * @return RedirectResponse
  83.      */
  84.     public function defaultAction(Request $request)
  85.     {
  86.         return $this->redirectToRoute('brulafine_show_packs');
  87.     }
  88.     /**
  89.      * @param Request $request
  90.      * @param ABTestManager $ABTestManager
  91.      * @param FacebookApiEventsManager $facebookApiEventsManager
  92.      * @return Response
  93.      */
  94.     #[Route(path: [
  95.         'fr' => '/nosPacks/',
  96.         'en' => '/ourPacks/',
  97.         'es' => '/nuestrosPacks/',
  98.         'it' => '/inostripacchi/',
  99.     ], name'brulafine_show_packs')]
  100.     public function displayPackAction(
  101.         Request $request,
  102.         ABTestManager $ABTestManager,
  103.         FacebookApiEventsManager $facebookApiEventsManager
  104.     ) {
  105.         $setup $this->getSetup();
  106.         $defaultProposedPacks $this->getPackFactory()->getDefaultProposedPacks($setup->getSite());
  107.         $personalisedPacks $ABTestManager->getPacksForTracking($setup->getTracking(), $defaultProposedPacks);
  108.         $facebookApiEventsManager->createEvent(FacebookApiEventsManager::VIEW_CONTENTnull$setup->getTracking());
  109.         return $this->staticAction($this->getTemplatesDir() . '/Default/pack.html.twig', [
  110.             'defaultProposedPacks' => $personalisedPacks,
  111.             'tracking' => $setup->getTracking()
  112.         ]);
  113.     }
  114.     /**
  115.      * @Route("/cart/custom", name="brulafine_updateCustomPack", methods={"POST"})
  116.      * @param Request $request
  117.      * @return Response
  118.      */
  119.     public function updateCustomPack(Request $request)
  120.     {
  121.         $setup $this->getSetup();
  122.         $packTemplateId $request->request->get('packTemplateId'0);
  123.         $items $request->request->get('item', []);
  124.         $newTemplatePack $this->getCartFactory()->getCustomTemplatePack($setup$packTemplateId$items);
  125.         if (null === $newTemplatePack) {
  126.             return $this->appendCookie(
  127.                 new JsonResponse(['has_error' => true], JsonResponse::HTTP_NOT_FOUND),
  128.                 $setup->getCookie()
  129.             );
  130.         }
  131.         return $this->appendCookie(
  132.             new JsonResponse(['view' => [
  133.                 'customPack' => $this->renderView(
  134.                     $this->getTemplatesDir() . '/Partials/customPackPartial.html.twig',
  135.                     ['sitePackTemplate' => $newTemplatePack]
  136.                 ),
  137.             ]]),
  138.             $setup->getCookie()
  139.         );
  140.     }
  141.     /**
  142.      * @Route("/cart/template/{packTemplateId}", name="brulafine_cart",requirements={"packTemplateId" = "\w+"})
  143.      * @param Request $request
  144.      * @param mixed $packTemplateId
  145.      * @param GeoIPManager $geoIPManager
  146.      * @param FacebookApiEventsManager $facebookApiEventsManager
  147.      * @param EntityManagerInterface $entityManager
  148.      * @param CartManager $cartManager
  149.      * @param AuthorizationCheckerInterface $authorizationChecker
  150.      * @param TranslatorInterface $translator
  151.      * @return RedirectResponse|Response
  152.      */
  153.     public function createCartAction(
  154.         Request $request,
  155.         mixed $packTemplateId,
  156.         GeoIPManager $geoIPManager,
  157.         FacebookApiEventsManager $facebookApiEventsManager,
  158.         EntityManagerInterface $entityManager,
  159.         CartManager $cartManager,
  160.         AuthorizationCheckerInterface $authorizationChecker,
  161.         TranslatorInterface $translator,
  162.     ) {
  163.         $setup $this->getSetup();
  164.         $cart $setup->getCart();
  165.         $user $setup->getUser();
  166.         $session $request->getSession();
  167.         $is_custom_pack false;
  168.         $switch_pack $request->get('switch-pack');
  169.         /** @var PackTemplate $packTemplate */
  170.         $packTemplate $entityManager
  171.             ->getRepository(PackTemplate::class)
  172.             ->findOneBy(['packTemplateId' => $packTemplateId]);
  173.         $sitePackTemplate $entityManager
  174.             ->getRepository(SitePackTemplate::class)
  175.             ->findOneBy(['packTemplate' => $packTemplate'site' => $setup->getSite(), 'active' => 1]);
  176.         if (!$sitePackTemplate) {
  177.             $this->addFlash('error''flashMessages.site.pleaseSelectPack');
  178.             return $this->redirectToRoute('brulafine_show_packs');
  179.         }
  180.         if (!$cart instanceof Cart || null !== $switch_pack) {
  181.             $items $request->get('item', []);
  182.             $items array_map('intval'$items);
  183.             if (!empty($items)) {
  184.                 $valid array_filter($items, function ($value) {
  185.                     return == $value;
  186.                 });
  187.                 if ($valid === $items) {
  188.                     $items = [];
  189.                 }
  190.             }
  191.             $currentCart $setup->getCart();
  192.             $currentCartAddress null;
  193.             // check if there was an address, if yes reuse it.
  194.             if ($currentCart instanceof Cart && !$currentCart->isPaid()) {
  195.                 if ($currentCart->getCartAddress() instanceof CartAddress) {
  196.                     $currentCartAddress $currentCart->getCartAddress();
  197.                     $currentCartAddress->setCart(null);
  198.                     $currentCart->setCartAddress(null);
  199.                 }
  200.                 $cartManager->cleanUpCurrentCart($currentCart);
  201.             }
  202.             $is_custom_pack $packTemplate->getPackTemplateType() == PackTemplate::CUSTOM_PACK;
  203.             if ($is_custom_pack) {
  204.                 $items $request->get('item', []);
  205.                 $items array_map('intval'$items);
  206.                 if ((!empty($items) && array_sum($items) <= 0) || empty($items)) {
  207.                     $this->addFlash('error''flashMessages.site.selectAtLeastOneProduct');
  208.                     return $this->redirectToRoute('brulafine_show_packs');
  209.                 }
  210.                 foreach ($items as $productQuantity) {
  211.                     if ($productQuantity 6) {
  212.                         $this->addFlash('error''flashMessages.site.productMaxQuantity');
  213.                         return $this->redirectToRoute('brulafine_show_packs');
  214.                     }
  215.                 }
  216.             }
  217.             // todo que faire avec le cart actuel ? (pour moi le trasher)
  218.             $cart $cartManager->makeCartFromPackTemplate(
  219.                 $packTemplate,
  220.                 $setup->getSite(),
  221.                 $setup->getTracking(),
  222.                 $setup->getAffiliate(),
  223.                 $items,
  224.                 $user,
  225.                 $currentCartAddress
  226.             );
  227.         }
  228.         if ($user instanceof User) {
  229.             $cart->setUser($user);
  230.             $cart->setTracking($user->getTracking());
  231.         }
  232.         $discountMessage '';
  233.         $discountCodeName $cartManager->getActualDiscountCode($cart);
  234.         $res $cartManager->addDiscountCode($cart$discountCodeName);
  235.         if ('success' === $res['status']) {
  236.             $discountMessage $translator->trans'flashMessages.site.discountCodeIsApplied', array('%discountCodeName%' => $cart->getDiscountCode()->getDiscountCodeName()), TranslationManager::TRANSLATION_DOMAIN_FLASH);
  237.         }
  238.         $tld $geoIPManager->getCountryCode($request->getClientIp());
  239.         $cart->setCartShippingCountry($tld);
  240.         $entityManager->flush();
  241.         $cartTotal $cartManager->computeCartTotal($cart);
  242.         // definir l'arbre de vie du cart
  243.         // new -> cart cree <- autoExpirer un cart et ses packs apres x temps dans le NEW state (ajouter cartStampCreation && cartStampLastUpdate)
  244.         // pendingIdentification -> on attend d'identifier le client ou anonyme
  245.         // pendingPayement -> on attend le payement
  246.         // pendingShipping
  247.         // shipped.
  248.         $session->set('currentCartId'$cart->getCartId());
  249.         if (true === $authorizationChecker->isGranted('ROLE_USER')) {
  250.             if ('' !== $discountMessage) {
  251.                 $this->addFlash('info'$discountMessage);
  252.             }
  253.             return $this->redirectToRoute('brulafine_shipping');
  254.         }
  255.         $session->set('seeTheCart'$cart->getCartId());
  256.         $regular_packs $entityManager
  257.             ->getRepository(SitePackTemplate::class)
  258.             ->getCachedAutoPacksForSite($setup->getSite());
  259.         $request->attributes->set(
  260.             'submit_button',
  261.             $translator->trans(
  262.                 'site.common.buttons.continue',
  263.                 array(),
  264.                 TranslationManager::TRANSLATION_DOMAIN_SITE
  265.             )
  266.         );
  267.         $facebookApiEventsManager->createEvent(FacebookApiEventsManager::ADD_TO_CART$cart$setup->getTracking());
  268.         $response $this->render($this->getTemplatesDir() . '/Default/cart.html.twig', [
  269.             'cart' => $cart,
  270.             'cartTotal' => $cartTotal,
  271.             'csrf_token' => $this->getLoginCsrfToken(),
  272.             'tracking' => $cart->getTracking(),
  273.             'site' => $setup->getSite(),
  274.             'regular_packs' => $regular_packs,
  275.             'is_custom_pack' => $is_custom_pack,
  276.             'discountMessage' => $discountMessage,
  277.         ]);
  278.         return $this->appendCookie($response$setup->getCookie());
  279.     }
  280.     /**
  281.      * @Route("/cart/discount", name="brulafine_discount")
  282.      * @param Request $request
  283.      * @param CartManager $cartFactory
  284.      * @return JsonResponse|RedirectResponse
  285.      * @throws Exception
  286.      */
  287.     public function addDiscountCodeAction(Request $requestCartManager $cartFactoryEntityManagerInterface $entityManagerTranslatorInterface $translator)
  288.     {
  289.         $setup $this->getSetup();
  290.         $user $setup->getUser();
  291.         if (!$user instanceof User) {
  292.             $user $entityManager->getRepository(User::class)->findOneBy(['id' => $request->getSession()->get(User::GUEST_USER_SESSION_KEY)]);
  293.         }
  294.         if (!$user instanceof User) {
  295.             if ($request->isXmlHttpRequest()) {
  296.                 return new JsonResponse(
  297.                     [
  298.                         'status' => 'error',
  299.                         'message' => $translator->trans'flashMessages.site.addDiscountCodeError', [], TranslationManager::TRANSLATION_DOMAIN_FLASH),
  300.                         'discountCodeName' => '',
  301.                         'view' => [
  302.                             'cartTableSummary' => ''
  303.                         ]
  304.                     ],
  305.                     400
  306.                 );
  307.             }
  308.             return $this->redirect($this->generateUrl("brulafine_home"));
  309.         }
  310.         // This request can't be accessed if there is no cart.
  311.         if (!$setup->getCart() instanceof Cart) {
  312.             if ($request->isXmlHttpRequest()) {
  313.                 return new JsonResponse(
  314.                     [
  315.                         'status' => 'error',
  316.                         'message' => $translator->trans'flashMessages.site.addDiscountCodeError', [], TranslationManager::TRANSLATION_DOMAIN_FLASH),
  317.                         'discountCodeName' => '',
  318.                         'view' => [
  319.                             'cartTableSummary' => ''
  320.                         ]
  321.                     ],
  322.                     400
  323.                 );
  324.             } else {
  325.                 $this->addFlash('error''flashMessages.site.addDiscountCodeError');
  326.                 return $this->redirectToRoute('brulafine_show_packs', []);
  327.             }
  328.         }
  329.         $result $cartFactory->discountCodeApplying($user$setup->getCart());
  330.         $gtmPromoCodeErrorEventContent '<script>
  331.     dataLayer.push({"event":"codepromo","errorString":"'.$translator->trans$result['message'], array(), TranslationManager::TRANSLATION_DOMAIN_FLASH).'","error_coupon":"'.$result['discountCodeName'].'"});
  332. </script>';
  333.         if ($request->isXmlHttpRequest()) {
  334.             $response = [
  335.                 'status' => $result['status'],
  336.                 'message' => $translator->trans$result['message'], array('%discountCodeName%' => $result['discountCodeName']), TranslationManager::TRANSLATION_DOMAIN_FLASH),
  337.                 'discountCodeName' => $result['discountCodeName'],
  338.                 'view' => [
  339.                     'cartTableSummary' => $this->renderView(
  340.                         $this->getTemplatesDir() . '/Partials/cartPartialSummary.html.twig',
  341.                         ['cart' => $result['cart'], 'cartTotal' => $result['cartTotal'], 'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  342.                     ),
  343.                     'GTMPromoCodeEventContent' => $gtmPromoCodeErrorEventContent
  344.                 ]
  345.             ];
  346.             if ($request->request->get('isSimpleOrder')) {
  347.                 $response['view']['payPalTabContent'] = $this->renderView(
  348.                     $this->getTemplatesDir() . '/Partials/payPal-tab-content.html.twig',
  349.                     ['cart' => $result['cart'], 'cartTotal' => $result['cartTotal'], 'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  350.                 );
  351.             }
  352.             return new JsonResponse(
  353.                 $response,
  354.                 200
  355.             );
  356.         } else {
  357.             $this->addFlash($result['status'], $translator->trans$result['message'], array('%discountCodeName%' => $result['discountCodeName']), TranslationManager::TRANSLATION_DOMAIN_FLASH));
  358.             return $this->redirectToRoute($result['redirectRoute'], $result['routeParams']);
  359.         }
  360.     }
  361.     /**
  362.      * @Route("/cart/credit-note", name="brulafine_credit_note")
  363.      * @param Request $request
  364.      * @param CartManager $cartFactory
  365.      * @return JsonResponse|RedirectResponse
  366.      * @throws Exception
  367.      */
  368.     public function addCreditNoteAction(Request $requestCartManager $cartFactoryEntityManagerInterface $entityManagerTranslatorInterface $translator)
  369.     {
  370.         $setup $this->getSetup();
  371.         $user $setup->getUser();
  372.         if (!$user instanceof User) {
  373.             $user $entityManager->getRepository(User::class)->findOneBy(['id' => $request->getSession()->get(User::GUEST_USER_SESSION_KEY)]);
  374.         }
  375.         if (!$user instanceof User) {
  376.             if ($request->isXmlHttpRequest()) {
  377.                 return new JsonResponse(
  378.                     [
  379.                         'status' => 'error',
  380.                         'view' => [
  381.                             'cartTableSummary' => ''
  382.                         ]
  383.                     ],
  384.                     400
  385.                 );
  386.             }
  387.             return $this->redirect($this->generateUrl("brulafine_home"));
  388.         }
  389.         $cart $setup->getCart();
  390.         // This request can't be accessed if there is no cart.
  391.         if (!$cart instanceof Cart) {
  392.             if ($request->isXmlHttpRequest()) {
  393.                 return new JsonResponse(
  394.                     [
  395.                         'status' => 'error',
  396.                         'view' => [
  397.                             'cartTableSummary' => ''
  398.                         ]
  399.                     ],
  400.                     400
  401.                 );
  402.             } else {
  403.                 return $this->redirectToRoute('brulafine_show_packs', []);
  404.             }
  405.         }
  406.         $requestData  = (array) json_decode($request->request->get('data'));
  407.         if ($requestData['useCreditNoteSelected']) {
  408.             $cartCreditNote $cart->hasCreditNoteAssigned(true);
  409.             /** @var UserCreditNote $userCreditNote */
  410.             $userCreditNote $user->getCreditNotes()[0];
  411.             if (!$cartCreditNote instanceof CartCreditNote) {
  412.                 //assign credit note to cart
  413.                 $cartCreditNote = new CartCreditNote();
  414.                 $cartCreditNote->setCart($cart);
  415.             }
  416.             $cartCreditNote->setValue($userCreditNote->getTotalValue());
  417.             $entityManager->persist($cartCreditNote);
  418.             $entityManager->flush();
  419.         } else {
  420.             $cartCreditNote $cart->hasCreditNoteAssigned(truetrue);
  421.             //remove value from credit note of the cart
  422.             if ($cartCreditNote instanceof CartCreditNote) {
  423.                 $cartCreditNote->setValue(null);
  424.                 $entityManager->persist($cartCreditNote);
  425.                 $entityManager->flush();
  426.             }
  427.         }
  428.         $entityManager->refresh($cart);
  429.         $result $cartFactory->creditNoteApplying($cart);
  430.         if ($request->isXmlHttpRequest()) {
  431.             $response = [
  432.                 'status' => $result['status'],
  433.                 'message' => $translator->trans'site.common.amountIsUpdated', array(), TranslationManager::TRANSLATION_DOMAIN_SITE),
  434.                 'view' => [
  435.                     'cartTableSummary' => $this->renderView(
  436.                         $this->getTemplatesDir() . '/Partials/cartSummary.html.twig',
  437.                         [
  438.                             'cart' => $result['cart'],
  439.                             'cartTotal' => $result['cartTotal'],
  440.                             'updateCommand' => true,
  441.                             'virement' => false,
  442.                             'bankDescriptor' => false
  443.                         ]
  444.                     )
  445.                 ],
  446.                 'cart' => $result['cart'],
  447.                 'cartTotal' => $result['cartTotal'],
  448.             ];
  449.             $response['view']['payPalTabContent'] = $this->renderView(
  450.                 $this->getTemplatesDir() . '/Partials/payPal-tab-content.html.twig',
  451.                 [
  452.                     'cart' => $result['cart'],
  453.                     'cartTotal' => $result['cartTotal'],
  454.                     'isSimpleOrder' => false
  455.                 ]
  456.             );
  457.             return new JsonResponse(
  458.                 $response,
  459.                 200
  460.             );
  461.         }
  462.     }
  463.     /**
  464.      * @Route("/cart/shipping", name="brulafine_shipping")
  465.      * @param Request $request
  466.      * @param UserAddressManager $userAddressManager
  467.      * @param LoggerInterface $logger
  468.      * @param CartSwitchManager $cartSwitchManager
  469.      * @return RedirectResponse|Response
  470.      * @throws Exception
  471.      */
  472.     public function shippingAction(
  473.         Request $request,
  474.         UserAddressManager $userAddressManager,
  475.         LoggerInterface $logger,
  476.         CartSwitchManager $cartSwitchManager,
  477.         GeoIPManager $geoIPManager,
  478.         EventDispatcherInterface $eventDispatcher,
  479.         SiteManager $siteManager,
  480.         FacebookApiEventsManager $facebookApiEventsManager,
  481.         CartManager $cartManager,
  482.         EntityManagerInterface $entityManager,
  483.         TranslatorInterface $translator
  484.     ) {
  485.         $setup $this->getSetup();
  486.         $cart $setup->getCart();
  487.         $user $setup->getUser();
  488.         if ($user instanceof User && $user->getAddress() instanceof UserAddress) {
  489.             $currentUserAddress = clone($user->getAddress());
  490.         } else {
  491.             $currentUserAddress = new UserAddress();
  492.         }
  493.         if (!$cart instanceof Cart) {
  494.             return $this->redirectToRoute('brulafine_show_packs');
  495.         }
  496.         if ($request->isXmlHttpRequest() && $request->request->get('loadProvinces')) {
  497.             $userAddress = new UserAddress();
  498.             $form $this->createForm(UserAddressType::class, $userAddress);
  499.             $form->handleRequest($request);
  500.             $response $this->render($this->getTemplatesDir() . '/Partials/addressForm.html.twig', [
  501.                 'form' => $form->createView(),
  502.                 'cart' => $cart,
  503.             ]);
  504.             return $this->appendCookie($response$setup->getCookie());
  505.         }
  506.         if (!$user instanceof User) {
  507.             return $this->redirectToRoute('brulafine_cart', ['packTemplateId' => $cart->getPacks()[0]->getPackTemplate()->getPackTemplateId()]);
  508.         }
  509.         $conditionResult $cartManager->isCartPurchasePossible($cart);
  510.         if ($conditionResult instanceof FailedPackCondition) {
  511.             $event = new AddedNonEligiblePackEvent($conditionResult->getPackTemplate(), $conditionResult->getTemplateCondition());
  512.             $eventDispatcher->dispatch($eventPackSubscriber::PACK_NON_ELIGIBLE_EVENT);
  513.             $cartManager->cleanUpCurrentCart($cart);
  514.             return $this->redirectToRoute('brulafine_show_packs');
  515.         }
  516.         $cartBill $cartManager->getBill($cart);
  517.         $userAddress = new UserAddress();
  518.         $userAddress->setCountry($geoIPManager->getCountryCode($request->getClientIp()));
  519.         if ($user->getAddress() instanceof UserAddress) {
  520.             $userAddress $user->getAddress();
  521.         }
  522.         $cart->setUser($user);
  523.         $entityManager->persist($cart);
  524.         $tld $userAddress->getCountry();
  525.         $form $this->createForm(UserAddressType::class, $userAddress);
  526.         $form->handleRequest($request);
  527.         $preventSells $siteManager->getYamlConfigParameter("frontEnd")['disableSells'] ?? false;
  528.         if ($form->isSubmitted() && $form->isValid() && !$preventSells) {
  529.             // $form->getData() holds the submitted values
  530.             // but, the original `$task` variable has also been updated
  531.             $route 'brulafine_payment';
  532.             /** @var UserAddress $submittedUserAddress */
  533.             $submittedUserAddress $form->getData();
  534.             $entityManager->persist($submittedUserAddress);
  535.             // check if the address was actually changed.
  536.             if ($userAddressManager->checkUserAddressHasChanged($currentUserAddress$submittedUserAddress)) {
  537.                 $submittedUserAddress $userAddressManager->updateUserAddressCountry($submittedUserAddress);
  538.                 $submittedUserAddress->setIsValidate(false);
  539.             }
  540.             if ($cart->getCartAddress() instanceof CartAddress && !$userAddressManager->checkAddressIsSameForCart($submittedUserAddress$cart->getCartAddress())) {
  541.                 $userAddressManager->updateCartAddress($cart->getCartAddress(), $submittedUserAddress);
  542.             } else {
  543.                 $cartAddress $userAddressManager->getAddressForCart($submittedUserAddress);
  544.                 $cart->setCartAddress($cartAddress);
  545.                 $cartAddress->setCart($cart);
  546.             }
  547.             $user->setAddress($submittedUserAddress);
  548.             $cart->setUser($user);
  549.             try {
  550.                 $entityManager->flush();
  551.             } catch (\Exception $e) {
  552.                 $logger->critical("Can't manage to save the address for a cart & user. {$user->getId()}, cart : {$cart->getCartId()}$e->getMessage());
  553.             }
  554.             try {
  555.                 $cartManager->transitState($cart'clientIdentification');
  556.                 $cartManager->transitState($cart'clientAddressFilling');
  557.                 $cartManager->transitState($cart'payment');
  558.             } catch (\Exception $e) {
  559.                 $logger->critical("Can't change state of the cart to payment. {$user->getId()}, cart : {$cart->getCartId()}, state {$cart->getCartState()}");
  560.             }
  561.             $cart->setCartShippingCountry($submittedUserAddress->getCountry());
  562.             $entityManager->flush();
  563.             if ($request->getLocale() == 'fr' && $cart->allowPush() && $cartSwitchManager->shouldDisplaySwitchForCart($setup->getCart(), true)) {
  564.                 $route 'brulafine_push_check_pack_switch';
  565.             }
  566.             if ($tld !== $submittedUserAddress->getCountry() && $cartManager->getBill($cart) != $cartBill) {
  567.                 $route 'brulafine_shipping';
  568.                 $this->addFlash('info''flashMessages.site.shippingPriceUpdated');
  569.             }
  570.             // If he got another order 30 mins before we are adding a confirmation page
  571.             if ($cartManager->hasOrderInDelay($user)) {
  572.                 $route 'brulafine_confirm';
  573.             }
  574.             return $this->redirectToRoute($route);
  575.         } elseif ($form->isSubmitted() && $form->isValid() && $preventSells) {
  576.             $errorMessage $siteManager->getYamlConfigParameter("frontEnd")['disabledButtonTitle'];
  577.             $this->addFlash("errors"$errorMessage);
  578.         }
  579.         $discountMessage '';
  580.         $discountCodeName $cartManager->getActualDiscountCode($cart);
  581.         $res $cartManager->addDiscountCode($cart$discountCodeName);
  582.         if ('success' === $res['status']) {
  583.             $discountMessage $translator->trans'flashMessages.site.discountCodeIsApplied', array('%discountCodeName%' => $cart->getDiscountCode()->getDiscountCodeName()), TranslationManager::TRANSLATION_DOMAIN_FLASH);
  584.         }
  585.         $facebookApiEventsManager->createEvent(FacebookApiEventsManager::COMPLETE_REGISTRATION$cart$setup->getTracking());
  586.         $response $this->render($this->getTemplatesDir() . '/Default/cart.html.twig', [
  587.             'form' => $form->createView(),
  588.             'cart' => $cart,
  589.             'cartTotal' => $cartManager->computeCartTotal($cart),
  590.             'defaultProposedPacks' => $this->getPackFactory()->getDefaultProposedPacks($setup->getSite()),
  591.             'tracking' => $setup->getTracking(),
  592.             'site' => $setup->getSite(),
  593.             'is_custom_pack' => $cart->getPacks()[0]->getPackType() === PackTemplate::CUSTOM_PACK,
  594.             'regular_packs' => $entityManager->getRepository(SitePackTemplate::class)->getCachedAutoPacksForSite($setup->getSite()),
  595.             'discountMessage' => $discountMessage,
  596.         ]);
  597.         return $this->appendCookie($response$setup->getCookie());
  598.     }
  599.     /**
  600.      * @Route("/cart/commande", name="brulafine_commande")
  601.      * @param Request $request
  602.      * @param UserAddressManager $userAddressManager
  603.      * @param LoggerInterface $logger
  604.      * @param GeoIPManager $geoIPManager
  605.      * @param CartManager $cartFactory
  606.      * @param EntityManagerInterface $entityManager
  607.      * @param SerializerInterface $serializer
  608.      * @param DeliveryProvidersManager $deliveryProvidersManager
  609.      * @param FacebookApiEventsManager $facebookApiEventsManager
  610.      * @param ABTestManager $ABTestManager
  611.      * @param SiteManager $siteManager
  612.      * @return RedirectResponse|Response
  613.      */
  614.     public function simpleOrderAction(
  615.         Request $request,
  616.         UserAddressManager $userAddressManager,
  617.         LoggerInterface $logger,
  618.         GeoIPManager $geoIPManager,
  619.         CartManager $cartFactory,
  620.         EntityManagerInterface $entityManager,
  621.         SerializerInterface $serializer,
  622.         DeliveryProvidersManager $deliveryProvidersManager,
  623.         FacebookApiEventsManager $facebookApiEventsManager,
  624.         ABTestManager $ABTestManager,
  625.         SiteManager $siteManager,
  626.         AuthorizationCheckerInterface $authorizationChecker
  627.     ) {
  628.         $setup $this->getSetup();
  629.         $environment $this->getParameter('kernel.environment');
  630.         // This code is specific to ease testing of 3ds payments
  631.         if ($request->query->get('3ds') || ($siteManager->getYamlConfigParameter('site_force_3ds') && !in_array($environment, ['test''dev']))) {
  632.             $request->getSession()->set('force_3ds'true);
  633.         }
  634.         if (!$ABTestManager->hasTest($setup->getTracking(), SiteABTest::BRU_QUICK_CHECKOUT_ON) && $request->getLocale() != 'it') {
  635.             return $this->redirectToRoute('brulafine_show_packs');
  636.         }
  637.         $setup $this->getSetup();
  638.         $cart $setup->getCart();
  639.         if ($authorizationChecker->isGranted('ROLE_USER')) {
  640.             $route 'brulafine_show_packs';
  641.             if ($cart instanceof Cart) {
  642.                 $route 'brulafine_shipping';
  643.             }
  644.             return $this->redirectToRoute($route);
  645.         }
  646.         $session $request->getSession();
  647.         if (!$cart instanceof Cart) {
  648.             if ($request->isXmlHttpRequest()) {
  649.                 return new JsonResponse([
  650.                     'result' => "KO",
  651.                     'message' => 'No cart!',
  652.                     'redirect' => $this->generateUrl('brulafine_show_packs')
  653.                 ], 401);
  654.             }
  655.             return $this->redirectToRoute('brulafine_show_packs');
  656.         }
  657.         if ($request->isXmlHttpRequest() && !$request->request->get('user_id')) {
  658.             return new JsonResponse([
  659.                 'result' => "KO",
  660.                 'message' => 'We need user here please!',
  661.             ], 401);
  662.         }
  663.         $userAddress = new UserAddress();
  664.         $userAddress->setCountry($geoIPManager->getCountryCode($request->getClientIp()));
  665.         /** @var User $user */
  666.         $user $entityManager->getRepository(User::class)->findOneById($request->request->get('user_id'));
  667.         if ($user instanceof User && $user->getAddress() instanceof UserAddress) {
  668.             $userAddress $user->getAddress();
  669.         }
  670.         $addressForm $this->createForm(UserAddressType::class, $userAddress);
  671.         $addressForm->handleRequest($request);
  672.         if ($request->isXmlHttpRequest()) {
  673.             if ($addressForm->isSubmitted() && $addressForm->isValid()) {
  674.                 /** @var UserAddress $submittedUserAddress */
  675.                 $submittedUserAddress $addressForm->getData();
  676.                 $entityManager->persist($submittedUserAddress);
  677.                 if ($user instanceof User && $user->getAddress() instanceof UserAddress) {
  678.                     $currentUserAddress = clone($user->getAddress());
  679.                 } else {
  680.                     $currentUserAddress = new UserAddress();
  681.                 }
  682.                 // check if the address was actually changed.
  683.                 if ($userAddressManager->checkUserAddressHasChanged($currentUserAddress$submittedUserAddress)) {
  684.                     $submittedUserAddress $userAddressManager->updateUserAddressCountry($submittedUserAddress);
  685.                     $submittedUserAddress->setIsValidate(false);
  686.                 }
  687.                 if ($cart->getCartAddress() instanceof CartAddress && !$userAddressManager->checkAddressIsSameForCart($submittedUserAddress$cart->getCartAddress())) {
  688.                     $userAddressManager->updateCartAddress($cart->getCartAddress(), $submittedUserAddress);
  689.                 } else {
  690.                     $cartAddress $userAddressManager->getAddressForCart($submittedUserAddress);
  691.                     $cart->setCartAddress($cartAddress);
  692.                     $cartAddress->setCart($cart);
  693.                 }
  694.                 $user->setAddress($submittedUserAddress);
  695.                 $cart->setUser($user);
  696.                 try {
  697.                     $entityManager->flush();
  698.                 } catch (\Exception $e) {
  699.                     $logger->critical("Can't manage to save the address for a cart & user. {$user->getId()}, cart : {$cart->getCartId()}");
  700.                 }
  701.                 try {
  702.                     $cartFactory->transitState($cart'clientIdentification');
  703.                     $cartFactory->transitState($cart'clientAddressFilling');
  704.                     $cartFactory->transitState($cart'payment');
  705.                 } catch (\Exception $e) {
  706.                     $logger->critical("Can't change state of the cart to payment. {$user->getId()}, cart : {$cart->getCartId()}, state {$cart->getCartState()}");
  707.                 }
  708.                 $cart->setCartShippingCountry($submittedUserAddress->getCountry());
  709.                 $entityManager->flush();
  710.                 $detailedPickupPointAddress null;
  711.                 if (null != $cart->getPickUpPoint()) {
  712.                     $detailedPickupPointAddress $deliveryProvidersManager->getPickUpPointAddressFromCart($cart);
  713.                 }
  714.                 $discountCodeName $cartFactory->getActualDiscountCode($cart);
  715.                 try {
  716.                     $res $cartFactory->addDiscountCode($cart$discountCodeName);
  717.                 } catch (\Exception $e) {
  718.                     return new JsonResponse([
  719.                         'result' => "KO",
  720.                         'message' => 'Problem with applying the code!',
  721.                     ], 401);
  722.                 }
  723.                 $cartTotal $cartFactory->computeCartTotal($cart);
  724.                 return new JsonResponse([
  725.                     'result' => "OK",
  726.                     'message' => 'valid',
  727.                     'userAddress' => $serializer->serialize($userAddress"json"),
  728.                     'userEmail' => $user->getEmail(),
  729.                     'detailedPickupPointAddress' => $detailedPickupPointAddress,
  730.                     'view' => [
  731.                         'payPalTabContent' => $this->renderView(
  732.                             $this->getTemplatesDir() . '/Partials/payPal-tab-content.html.twig',
  733.                             ['cart' => $cart'cartTotal' => $cartTotal'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  734.                         )
  735.                     ]
  736.                 ], 200);
  737.             } else {
  738.                 $formErrorsResolver = new FormErrorsResolver($addressForm);
  739.                 $errors $formErrorsResolver->resolve();
  740.                 return new JsonResponse([
  741.                     'result' => "KO",
  742.                     'message' => 'There is errors in the form!',
  743.                     'submit' => $addressForm->isSubmitted(),
  744.                     'errors' => $errors
  745.                 ], 401);
  746.             }
  747.         }
  748.         $cardPayment = new CardPayment($request->getClientIp(), $request->headers->get('User-Agent'));
  749.         $paymentForm $this->createForm(UserPaymentType::class, $cardPayment);
  750.         $paymentForm->handleRequest($request);
  751.         $formType 'creditcard';
  752.         $environment $this->container->getParameter('kernel.environment');
  753.         $facebookApiEventsManager->createEvent(FacebookApiEventsManager::LEAD$cart$setup->getTracking());
  754.         $response $this->render($this->getTemplatesDir() . '/Default/cart-simple-oder.html.twig', [
  755.             'addressForm' => $addressForm->createView(),
  756.             'paymentForm' => $paymentForm->createView(),
  757.             'forceTransfer' => $session->get('forceTransfert'0),
  758.             'showBankTransfer' => $session->get('showBankTransfer'0),
  759.             'cart' => $cart,
  760.             'tracking' => $setup->getTracking(),
  761.             'cartTotal' => $cartFactory->computeCartTotal($cart),
  762.             'formType' => $request->query->get('formType'$formType),
  763.             'disableCbForm' => false,
  764.             'environment' => $environment,
  765.         ]);
  766.         return $this->appendCookie($response$setup->getCookie());
  767.     }
  768.     /**
  769.      * @Route("/cart", name="brulafine_updateCart")
  770.      * @param Request $request
  771.      * @return Response
  772.      */
  773.     public function updateCartAction(Request $requestLoggerInterface $loggerDeliveryProvidersManager $deliveryProvidersManager)
  774.     {
  775.         $setup $this->getSetup();
  776.         try {
  777.             $this->getCartFactory()->updateCartProductQuantity(
  778.                 $setup,
  779.                 $request->request->get('packIndex'),
  780.                 $request->request->get('packProductIndex'),
  781.                 $request->request->get('productQuantity')
  782.             );
  783.             $cart $setup->getCart();
  784.             $cartTotal $this->getCartFactory()->computeCartTotal($cart);
  785.             $shippingPrices $deliveryProvidersManager->getShippingOptions($cart);
  786.             $template 'cartTablePack';
  787.             if ($cart->getPacks()[0]->getPackType() === Pack::CUSTOM_PACK) {
  788.                 $template 'cartTableCustomPack';
  789.             }
  790.             //check if User clicks Off or On the Coaching option and create an event for each
  791.             $tracking $setup->getTracking();
  792.             $response = new JsonResponse(['view' => [
  793.                 'cartTableBody' => $this->renderView(
  794.                     $this->getTemplatesDir() . '/Partials/' $template '.html.twig',
  795.                     ['cartTotal' => $cartTotal'cart' => $cart'tracking' => $tracking'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  796.                 ),
  797.                 'cartTableSummary' => $this->renderView(
  798.                     $this->getTemplatesDir() . '/Partials/cartPartialSummary.html.twig',
  799.                     ['cartTotal' => $cartTotal'cart' => $cart'tracking' => $tracking'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  800.                 ),
  801.                 'cartPopup' => $this->renderView(
  802.                     $this->getTemplatesDir() . '/Partials/cartPopup.html.twig',
  803.                     ['cartTotal' => $cartTotal'cart' => $cart'tracking' => $tracking'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  804.                 ),
  805.                 'payPalTabContent' => $this->renderView(
  806.                     $this->getTemplatesDir() . '/Partials/payPal-tab-content.html.twig',
  807.                     ['cart' => $cart'cartTotal' => $cartTotal'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  808.                 ),
  809.             ],
  810.                 'shippingPrices' => $shippingPrices
  811.             ]);
  812.             return $this->appendCookie($response$setup->getCookie());
  813.         } catch (Exception $e) {
  814.             $response = new JsonResponse([
  815.                 'has_error' => true,
  816.                 'message' => $e->getMessage(),
  817.                 'message1' => $e->getLine() . $e->getFile(),
  818.             ], JsonResponse::HTTP_NOT_FOUND);
  819.             return $this->appendCookie($response$setup->getCookie());
  820.         }
  821.     }
  822.     /**
  823.      * @Route("/cart/update/shipping-prices", name="brulafine_update_shipping_prices")
  824.      * @param Request $request
  825.      * @param DeliveryProvidersManager $deliveryProvidersManager
  826.      * @param EntityManagerInterface $entityManager
  827.      * @return Response
  828.      */
  829.     public function updateCartShippingAction(Request $requestDeliveryProvidersManager $deliveryProvidersManagerEntityManagerInterface $entityManager)
  830.     {
  831.         $setup $this->getSetup();
  832.         $cart $setup->getCart();
  833.         if (!$cart instanceof Cart) {
  834.             $response = new JsonResponse(
  835.                 [
  836.                     'response' => 'KO',
  837.                     'message' => 'You must have a cart here!'
  838.                 ]
  839.             );
  840.             return $this->appendCookie($response$setup->getCookie());
  841.         }
  842.         $country $request->request->get('addressCountry');
  843.         $shippingRule $request->request->get('shippingRule');
  844.         if (null != $country) {
  845.             $cart->setCartShippingCountry($country);
  846.             $user $cart->getUser();
  847.             if ($user instanceof User && $user->getAddress() instanceof UserAddress) {
  848.                 $user->getAddress()->setCountry($country);
  849.             }
  850.         }
  851.         if (null != $shippingRule) {
  852.             $cart->setShippingRule($shippingRule);
  853.         }
  854.         if ($deliveryProvidersManager->ruleIsToAddress($shippingRule)) {
  855.             $cart->setPickUpPoint(null);
  856.         }
  857.         $shippingPrices $deliveryProvidersManager->getShippingOptions($cart$country);
  858.         if (count($shippingPrices) == 1) {
  859.             $cart->setShippingRule(null);
  860.         }
  861.         $entityManager->flush();
  862.         $cartTotal $this->getCartFactory()->computeCartTotal($cart);
  863.         $tracking $setup->getTracking();
  864.         $response = new JsonResponse(
  865.             [
  866.                 'response' => 'OK',
  867.                 'shippingPrices' => $shippingPrices,
  868.                 'view' => [
  869.                     'cartTableSummary' => $this->renderView(
  870.                         $this->getTemplatesDir() . '/Partials/cartPartialSummary.html.twig',
  871.                         ['cartTotal' => $cartTotal'cart' => $cart'tracking' => $tracking'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  872.                     ),
  873.                     'payPalTabContent' => $this->renderView(
  874.                         $this->getTemplatesDir() . '/Partials/payPal-tab-content.html.twig',
  875.                         ['cart' => $cart'cartTotal' => $cartTotal'isSimpleOrder' => $request->request->get('isSimpleOrder')]
  876.                     ),
  877.                 ]
  878.             ]
  879.         );
  880.         return $this->appendCookie($response$setup->getCookie());
  881.     }
  882.     /**
  883.      * @Route("/cart/switch", name="brulafine_push_check_pack_switch")
  884.      * @param Request $request
  885.      * @param CartSwitchManager $cartSwitchManager
  886.      * @return RedirectResponse|Response
  887.      */
  888.     public function cartSwitchAction(Request $requestCartSwitchManager $cartSwitchManager)
  889.     {
  890.         $setup $this->getSetup();
  891.         $cart $setup->getCart();
  892.         if (!$cart instanceof Cart || !$cartSwitchManager->shouldDisplaySwitchForCart($setup->getCart())) {
  893.             return $this->redirectToRoute('brulafine_payment');
  894.         }
  895.         $currentPack $this->getCartFactory()->getCurrentPack($cart);
  896.         if (!$currentPack) {
  897.             return $this->redirectToRoute('brulafine_payment');
  898.         }
  899.         $cart $setup->getCart();
  900.         //cart gratuit
  901.         if (null !== ($discountCode $cart->getDiscountCode()) && DiscountCode::FREE_PURCHASE === $discountCode->getDiscountCodeType()) {
  902.             return $this->redirectToRoute('brulafine_payment');
  903.         }
  904.         //si custom pack .. rien a faire ici
  905.         if ($cart->isWithCustomPack()) {
  906.             return $this->redirectToRoute('brulafine_payment');
  907.         }
  908.         // if cart doesn't allow push, move away
  909.         if (!$cart->allowPush()) {
  910.             return $this->redirectToRoute('brulafine_payment');
  911.         }
  912.         //si AB-testing activated .. and user must not view the switch then
  913.         //user has nothing to do here
  914.         if (!$cart->getUser() instanceof User) {
  915.             return $this->redirectToRoute('brulafine_show_packs');
  916.         } else {
  917.             $userSettings $cart->getUser()->getSettings();
  918.             $show_cart_switch $userSettings[UserSettings::AB_TEST]['show_cart_switch'] ?? true;
  919.         }
  920.         if (!$show_cart_switch) {
  921.             return $this->redirectToRoute('brulafine_payment');
  922.         }
  923.         // Chris don't want anymore to see only once the switch.
  924. //        $session = $request->getSession();
  925. //        if ($session->get('has_switched', false)) {
  926. //            return $this->redirectToRoute('brulafine_payment');
  927. //        }
  928.         $result $this->getCartFactory()->getNextPackTemplate($cart);
  929.         if (!$result || null === $result['packTemplates']) {
  930. //            $session->set('has_switched', true);
  931.             return $this->redirectToRoute('brulafine_payment');
  932.         }
  933.         $possibleNextPacksData $this->getCartFactory()->generatePossibleNextPacksData($result$cart$setup);
  934.         $response $this->render($this->getTemplatesDir() . '/Default/push.html.twig', [
  935.             'currentPack' => $currentPack,
  936.             'currentCartBill' => $this->getCartFactory()->getBill($cart),
  937.             'currentCart' => $cart,
  938.             'possibleNextPacksData' => $possibleNextPacksData,
  939.             'tracking' => $setup->getTracking(),
  940.             'site' => $setup->getSite(),
  941.         ]);
  942. //        $session->set('has_switched', true);
  943.         return $this->appendCookie($response$setup->getCookie());
  944.     }
  945.     /**
  946.      * @Route("/cart/payment/{packTemplateId}/{hasCoaching}", name="brulafine_payment",requirements={"packTemplateId" = "\d+", "hasCoaching" = "\d+"}, defaults={"packTemplateId" = "0", "hasCoaching" = "1"})
  947.      * @param Request $request
  948.      * @param LoggerInterface $logger
  949.      * @param UserAddressManager $userAddressManager
  950.      * @param EventDispatcherInterface $eventDispatcher
  951.      * @param GeoIPManager $geoIPManager
  952.      * @param FacebookApiEventsManager $facebookApiEventsManager
  953.      * @param EntityManagerInterface $entityManager
  954.      * @param SiteManager $siteManager
  955.      * @param ABTestManager $ABTestManager
  956.      * @param null|int $packTemplateId
  957.      * @param mixed $hasCoaching
  958.      * @return RedirectResponse|Response
  959.      */
  960.     public function paymentAction(
  961.         Request $request,
  962.         LoggerInterface $logger,
  963.         UserAddressManager $userAddressManager,
  964.         EventDispatcherInterface $eventDispatcher,
  965.         GeoIPManager $geoIPManager,
  966.         FacebookApiEventsManager $facebookApiEventsManager,
  967.         EntityManagerInterface $entityManager,
  968.         SiteManager $siteManager,
  969.         ABTestManager $ABTestManager,
  970.         EmailManager $emailManager,
  971.         ShortId $shortId,
  972.         TrackingManager $trackingManager,
  973.         TranslatorInterface $translator,
  974.         null|int $packTemplateId 0,
  975.         int $hasCoaching 1
  976.     ) {
  977.         $setup $this->getSetup();
  978.         $cartFactory $this->getCartFactory();
  979.         $user $this->getUser();
  980.         $session $request->getSession();
  981.         if (!$user instanceof User && $session->has(User::GUEST_USER_SESSION_KEY)) {
  982.             $user $entityManager->getRepository(User::class)->findOneBy(['id' => $request->getSession()->get(User::GUEST_USER_SESSION_KEY)]);;
  983.         }
  984.         $environment $this->getParameter("kernel.environment");
  985.         //detecte le cart a afficher et reellement payer
  986.         try {
  987.             $cart $cartFactory->getPaymentCart($setup$packTemplateId$hasCoaching$userAddressManager);
  988.         } catch (CartAlreadyPaidException $e) {
  989.             // The user should not reach this page with an already paid cart, send him to the last cart paid page
  990.             $cart $cartFactory->getLastPaidCart($user);
  991.             if ($cart instanceof Cart) {
  992.                 $cartFactory->removeCartFromSession();
  993.                 $logger->notice($e->getMessage() . ", redirecting to the last paid cart over page {$cart->getCartId()}{$cart->getCartCreateAt()->format("Y-m-d H:i:s")}");
  994.                 return $this->redirectToRoute('brulafine_over', [
  995.                     'shortId' => $shortId->encode($cart->getCartId())
  996.                 ]);
  997.             }
  998.             // if no paid cart is found, emulate previous behavior.
  999.             $cartFactory->removeCartFromSession();
  1000.             $logger->notice($e->getMessage());
  1001.             if ($request->isXmlHttpRequest()) {
  1002.                 return new JsonResponse([
  1003.                     'result' => "ko",
  1004.                     'message' => 'System Error!',
  1005.                     'redirect' => $this->generateUrl('brulafine_show_packs')
  1006.                 ], 401);
  1007.             }
  1008.             return $this->redirectToRoute('brulafine_show_packs');
  1009.         } catch (Throwable $e) {
  1010.             $cartFactory->removeCartFromSession();
  1011.             $logger->notice($e->getMessage());
  1012.             if ($request->isXmlHttpRequest()) {
  1013.                 return new JsonResponse([
  1014.                     'result' => "ko",
  1015.                     'message' => 'System Error!',
  1016.                     'exception' => $e->getMessage(),
  1017.                     'redirect' => $this->generateUrl('brulafine_show_packs')
  1018.                 ], 401);
  1019.             }
  1020.             return $this->redirectToRoute('brulafine_show_packs');
  1021.         }
  1022.         //sauve le cart a payer dans la DB
  1023.         $session $request->getSession();
  1024.         $session->set('currentCartId'$cart->getCartId());
  1025.         $entityManager->persist($cart);
  1026.         $entityManager->flush();
  1027.         $trStatuses = [Transaction::OK];
  1028.         // si une transaction est deja en cours on le balance sur OVER
  1029.         $transaction $entityManager->getRepository(Transaction::class)->findOneBy([
  1030.             'cart' => $cart,
  1031.             'transactionStatus' => $trStatuses,
  1032.         ]);
  1033.         if ($transaction instanceof Transaction) {
  1034.             if (Transaction::OK === $transaction->getTransactionStatus()) {
  1035.                 $cartFactory->transitState($cart'paymentSuccess');
  1036.                 $entityManager->flush();
  1037.                 if ($request->isXmlHttpRequest()) {
  1038.                     return new JsonResponse([
  1039.                         'result' => "ko",
  1040.                         'message' => 'Already payed!',
  1041.                         'redirect' => $this->generateUrl('brulafine_over', ['shortId' => $shortId->encode($cart->getCartId())])
  1042.                     ], 401);
  1043.                 }
  1044.                 return $this->redirectToRoute('brulafine_over', [
  1045.                     'shortId' => $shortId->encode($cart->getCartId()),
  1046.                 ]);
  1047.             }
  1048.             $this->addFlash(
  1049.                 'transactionMessage',
  1050.                 'flashMessages.site.cartAlreadyPaid'
  1051.             );
  1052.             if ($request->isXmlHttpRequest()) {
  1053.                 return new JsonResponse([
  1054.                     'result' => "ko",
  1055.                     'message' => $translator->trans'flashMessages.site.cartAlreadyPaid', array(), TranslationManager::TRANSLATION_DOMAIN_FLASH),
  1056.                 ], 401);
  1057.             }
  1058.             return $this->redirectToRoute('brulafine_payment', [
  1059.                 'packTemplateId' => $packTemplateId,
  1060.                 'hasCoaching' => $hasCoaching,
  1061.             ]);
  1062.         }
  1063.         $purchase = new Purchase();
  1064.         $bypassPayment false;
  1065.         //FREE PURCHASE
  1066.         if ($cartFactory->cartIsEligibleForFreePurchase($cart)) {
  1067.             $purchase->setPaymentMethod(Purchase::PAYMENT_FREE);
  1068.             $cart->setCartBillingType(Cart::BILLING_TYPE_FREE);
  1069.             $bypassPayment true;
  1070.         }
  1071.         //BANK TRANSFER
  1072.         $bankTransfer = new BankTransfer($request->getClientIp(), $request->headers->get('User-Agent'));
  1073.         $bankTransfertForm $this->createForm(BankTransferType::class, $bankTransfer);
  1074.         $bankTransfertForm->handleRequest($request);
  1075.         if (!$bypassPayment && $bankTransfertForm->isSubmitted() && $bankTransfertForm->isValid()) {
  1076.             $purchase->setPaymentMethod(Purchase::PAYMENT_BANK_TRANSFERT);
  1077.             $cart->setCartBillingType(Cart::BILLING_TYPE_ALTERNATIVE);
  1078.             $bypassPayment true;
  1079.         }
  1080.         //PAYPAL
  1081.         $paypalPayment = new PaypalPayment($request->getClientIp(), $request->headers->get('User-Agent'));
  1082.         $paypalForm $this->createForm(PaypalPaymentType::class, $paypalPayment);
  1083.         $paypalForm->handleRequest($request);
  1084.         if (!$bypassPayment && $paypalForm->isSubmitted() && $paypalForm->isValid()) {
  1085.             $purchase->setPaymentMethod(Purchase::PAYMENT_PAYPAL);
  1086.             $cart->setCartBillingType(Cart::BILLING_TYPE_PAYPAL);
  1087.             $bypassPayment true;
  1088.         }
  1089.         //recupere le client qui doit payer le cart
  1090.         $user $cart->getUser();
  1091.         $site $setup->getSite();
  1092.         // This code is specific to ease testing of 3ds payments
  1093.         if ($request->query->get('3ds') && !$bypassPayment || ($siteManager->getYamlConfigParameter('site_force_3ds') && !in_array($environment, ['test''dev']))) {
  1094.             $session->set('force_3ds'true);
  1095.         }
  1096.         // Check if there is an AB test that force the 3DS for this customer.
  1097.         $abTestManager $ABTestManager;
  1098.         if (!$bypassPayment && ($abTestManager->hasTest($trackingManager->getCurrentTracking(), SiteABTest::FORCED_3DS_PURCHASE_ON) || $abTestManager->cartHasTest($cartSiteABTest::FORCED_3DS_PURCHASE_ON))) {
  1099.             $session->set('force_3ds'true);
  1100.         }
  1101.         //get the submited payment infos (if so)
  1102.         $cardPayment = new CardPayment($request->getClientIp(), $request->headers->get('User-Agent'));
  1103.         $form $this->createForm(UserPaymentType::class, $cardPayment);
  1104.         $form->handleRequest($request);
  1105.         if (!$bypassPayment && !($form->isSubmitted() && $form->isValid())) {
  1106.             $now date_create();
  1107.             $disableCbFormData $session->get('disableCbForm', ['userId' => -1'dateEnd' => $now]);
  1108.             $disableCbForm false !== $disableCbFormData
  1109.                 && $user->getId() == $disableCbFormData['userId']
  1110.                 && $now $disableCbFormData['dateEnd'];
  1111.             $formType 'creditcard';
  1112.             if (Purchase::PAYMENT_BANK_TRANSFERT == $purchase->getPaymentMethod()) {
  1113.                 $formType 'banktransfer';
  1114.             } elseif (UserPayment::TYPE_BCMC === $cardPayment->getCardType()) {
  1115.                 $formType 'bancontact';
  1116.             }
  1117.             if ($form->isSubmitted() && !$form->isValid()) {
  1118.                 $errorMsg $form->getErrors()->current() instanceof FormError $form->getErrors()->current()->getMessage() : '';
  1119.                 $paymentErrorEvent = new PaymentErrorEvent($errorMsgnull$cart);
  1120.                 $eventDispatcher->dispatch($paymentErrorEventPaymentSubscriber::PAYMENT_ERROR);
  1121.                 if ($request->isXmlHttpRequest()) {
  1122.                     $formErrorsResolver = new FormErrorsResolver($form);
  1123.                     $errors $formErrorsResolver->resolve();
  1124.                     if (!empty($errors)) {
  1125.                         $errorMsg $translator->trans('site.purchaseForm.errors.2', [], TranslationManager::TRANSLATION_DOMAIN_SITE);
  1126.                         if (isset($errors['terms'])) {
  1127.                             $errorMsg $translator->trans('site.purchaseForm.errors.1', [], TranslationManager::TRANSLATION_DOMAIN_SITE);
  1128.                         }
  1129.                     }
  1130.                     if (isset($errors['expirationYear']) || isset($errors['expirationMonth'])) {
  1131.                         $errorMsg $translator->trans('site.purchaseForm.errors.3', [], TranslationManager::TRANSLATION_DOMAIN_SITE);
  1132.                     }
  1133.                     return new JsonResponse([
  1134.                         'result' => 'ko',
  1135.                         'formType' => $formType,
  1136.                         'disableCbForm' => $disableCbForm,
  1137.                         'message' => $errorMsg,
  1138.                     ], 401);
  1139.                 }
  1140.             }
  1141.             $defaultPacks $this->getPackFactory()->getDefaultProposedPacks($site);
  1142.             $defaultProposedPack $abTestManager->getPacksForTracking($setup->getTracking(), $defaultPacks);
  1143.             $facebookApiEventsManager->createEvent(FacebookApiEventsManager::ADD_PAYMENT_INFO$cart$setup->getTracking());
  1144.             $response $this->render($this->getTemplatesDir() . '/Default/payment.html.twig', [
  1145.                 'cart' => $cart,
  1146.                 'cartTotal' => $cartFactory->computeCartTotal($cart),
  1147.                 'form' => $form->createView(),
  1148.                 'bankTransferForm' => $bankTransfertForm->createView(),
  1149.                 'paypalForm' => $paypalForm->createView(),
  1150.                 'isBillingTypeAlternative' => $cart->getCartBillingType() === Cart::BILLING_TYPE_ALTERNATIVE,
  1151.                 'defaultProposedPacks' => $defaultProposedPack,
  1152.                 'tracking' => $setup->getTracking(),
  1153.                 'site' => $setup->getSite(),
  1154.                 'forceTransfer' => $session->get('forceTransfer'0),
  1155.                 'showBankTransfer' => $session->get('showBankTransfer'0),
  1156.                 'disableCbForm' => $disableCbForm,
  1157.                 'tld' => $geoIPManager->getCountryCode($request->getClientIp()),
  1158.                 'formType' => $request->query->get('formType'$formType),
  1159.                 'environment' => $environment
  1160.             ]);
  1161.             return $this->appendCookie($response$setup->getCookie());
  1162.         }
  1163.         $commandeId $shortId->encode($cart->getCartId());
  1164.         if (Purchase::PAYMENT_PAYPAL == $purchase->getPaymentMethod()) {
  1165.             $userPayment $paypalPayment;
  1166.         } else {
  1167.             $userPayment $form->getData();
  1168.         }
  1169.         // if set, always force the payment in 3ds.
  1170.         if (!$bypassPayment && $session->get('force_3ds')) {
  1171.             $purchase->setPaymentMethod(Purchase::PAYMENT_3DS);
  1172.             $payment3DSSwapEvent = new PaymentSwap3DSEvent(PaymentSwap3DSEvent::REASON_OTHER$cart);
  1173.             $eventDispatcher->dispatch($payment3DSSwapEventPaymentSubscriber::PAYMENT_3DS_SWAP);
  1174.         }
  1175.         try {
  1176.             $this->getBillingFactory()->processCart($cart$site$user$userPayment$purchase);
  1177.             $cartTotal $cartFactory->computeCartTotal($cart);
  1178.             $this->addFlash('conversion_tag''show');
  1179.             $session->set('justPurchased'true);
  1180.             // if it's a paypal purchase we return json data
  1181.             if (Purchase::PAYMENT_PAYPAL == $purchase->getPaymentMethod()) {
  1182.                 if (Purchase::STATUS_SUCCESS === $purchase->getStatus()) {
  1183.                     return $response = new JsonResponse(
  1184.                         [
  1185.                             'result' => 'ok'
  1186.                             'redirect' => $this->generateUrl('brulafine_over', ['shortId' => $commandeId])
  1187.                         ],
  1188.                         200
  1189.                     );
  1190.                 } else {
  1191.                     return $response = new JsonResponse(['result' => 'fail'], 401);
  1192.                 }
  1193.             }
  1194.             if (Purchase::STATUS_SUCCESS === $purchase->getStatus()) {
  1195.                 if ($request->isXmlHttpRequest()) {
  1196.                     return new JsonResponse([
  1197.                         'result' => 'ok',
  1198.                         'redirect' => $this->generateUrl('brulafine_over', ['shortId' => $commandeId]),
  1199.                     ], 200);
  1200.                 } else {
  1201.                     return $this->redirectToRoute('brulafine_over', ['shortId' => $commandeId]);
  1202.                 }
  1203.             }
  1204.             if (Purchase::STATUS_FAILED === $purchase->getStatus()) {
  1205.                 $metaData $purchase->getMetaData();
  1206.                 $msgError 'flashMessages.site.errorDuringTransaction';
  1207.                 $errorText $metaData['errorText'];
  1208.                 $disableCbForm $metaData['disableCbForm'];
  1209.                 if ([] !== $disableCbForm) {
  1210.                     $session->set('disableCbForm'$disableCbForm);
  1211.                 }
  1212.                 $showBankTransfer $metaData['showBankTransfer'];
  1213.                 if ($showBankTransfer) {
  1214.                     $session->set('showBankTransfer'1);
  1215.                 }
  1216.                 $forceTransfert $metaData['forceTransfert'];
  1217.                 if ($forceTransfert) {
  1218.                     $session->set('forceTransfert'1);
  1219.                 }
  1220.                 $errorText array_filter($errorText, function (string $value) {
  1221.                     return '' !== $value;
  1222.                 });
  1223.                 if (!empty($errorText) && is_array($errorText)) {
  1224.                     $this->addFlash('error'$errorText[0]);
  1225.                     if (isset($errorText[1])) {
  1226.                         $this->addFlash('additionnalInstructions'$errorText[1]);
  1227.                     }
  1228.                 } else {
  1229.                     $this->addFlash('error'$msgError);
  1230.                 }
  1231.                 $formType 'creditcard';
  1232.                 if (Purchase::PAYMENT_BANK_TRANSFERT == $purchase->setPaymentMethod(Purchase::PAYMENT_BANK_TRANSFERT)) {
  1233.                     $formType 'banktransfer';
  1234.                 } elseif (UserPayment::TYPE_BCMC === $userPayment->getCardType()) {
  1235.                     $formType 'bancontact';
  1236.                 }
  1237.                 if ($request->isXmlHttpRequest()) {
  1238.                     return new JsonResponse([
  1239.                         'result' => "ko",
  1240.                         'message' => $translator->trans($msgError, [], TranslationManager::TRANSLATION_DOMAIN_FLASH),
  1241.                         'formType' => $formType,
  1242.                         'forceTransfert' => $forceTransfert,
  1243.                         'showBankTransfer' => $showBankTransfer
  1244.                     ], 401);
  1245.                 }
  1246.                 return $this->redirectToRoute('brulafine_payment', [
  1247.                     'packTemplateId' => 0,
  1248.                     'hasCoaching' => 1,
  1249.                     'formType' => $formType,
  1250.                 ]);
  1251.             }
  1252.             if (Purchase::PAYMENT_BANK_TRANSFERT === $purchase->getPaymentMethod()) {
  1253.                 if ($request->isXmlHttpRequest()) {
  1254.                     return new JsonResponse([
  1255.                         'result' => "ko",
  1256.                         'redirect' => $this->generateUrl('brulafine_over', ['shortId' => $commandeId]),
  1257.                     ], 401);
  1258.                 }
  1259.                 return $this->redirectToRoute('brulafine_over', ['shortId' => $commandeId]);
  1260.             }
  1261.             if (Purchase::PAYMENT_3DS === $purchase->getPaymentMethod()) {
  1262.                 $code = new CodeHtml3DSLog();
  1263.                 $code->setDate(new \DateTime());
  1264.                 $code->setCode($purchase->getMetaData()['code']);
  1265.                 $code->setTransaction($purchase->getPreviousTransaction());
  1266.                 $entityManager->persist($code);
  1267.                 $entityManager->flush();
  1268.                 if ($request->isXmlHttpRequest()) {
  1269.                     $content $this->render($this->getTemplatesDir() . '/Default/display-html-code.html.twig', [
  1270.                         'code' => $purchase->getMetaData()['code'],
  1271.                     ])->getContent();
  1272.                     return new JsonResponse([
  1273.                         'result' => 'ok',
  1274.                         'mode' => '3ds',
  1275.                         'content' => $content
  1276.                     ], 200);
  1277.                 }
  1278.                 return $this->render($this->getTemplatesDir() . '/Default/display-html-code.html.twig', [
  1279.                     'code' => $purchase->getMetaData()['code'],
  1280.                 ]);
  1281.             }
  1282.             throw new \RuntimeException(sprintf('Undefined %s Purchase method'$purchase->getPaymentMethod()));
  1283.         } catch (Throwable $e) {
  1284.             $message 'Une erreur est survenue apres transaction.' PHP_EOL
  1285.                 'CLIENT EMAIL = ' $user->getUsername() . PHP_EOL
  1286.                 'CART ID = ' $cart->getCartId() . PHP_EOL
  1287.                 'ERROR TYPE = ' get_class($e) . PHP_EOL
  1288.                 'ERROR CODE = ' $e->getCode() . PHP_EOL
  1289.                 'ERROR Message = ' $e->getMessage() . PHP_EOL
  1290.                 'ERROR TRACE = ' $e->getTraceAsString() . PHP_EOL;
  1291.             $emailManager->sendPaymentAlert("[{$cartFactory->siteManager->getCurrentSite()->getSiteName()}] payment error after transaction succeeded"$message);
  1292.             $logger->error($e->getMessage());
  1293.             $logger->critical("[{$cartFactory->siteManager->getCurrentSite()->getSiteName()}] payment error after transaction succeeded => " $message);
  1294.             $this->addFlash('conversion_tag''show');
  1295.             $session->set('justPurchased'true);
  1296.             if ($request->isXmlHttpRequest()) {
  1297.                 return new JsonResponse([
  1298.                     'result' => "ok",
  1299.                     'redirect' => $this->generateUrl('brulafine_over', ['shortId' => $commandeId]),
  1300.                 ], 200);
  1301.             }
  1302.             return $this->redirectToRoute('brulafine_over', ['shortId' => $commandeId]);
  1303.         }
  1304.     }
  1305.     /**
  1306.      * This is used when the user is waiting for the paypal validation of his payment.
  1307.      * Note : Normally the payment is instant and included in the flow, but in cas of problem this is the backup.
  1308.      *
  1309.      * @Route("/cart/paypal/payment/check/{cartId}", name="brulafine_paypal_payment_check")
  1310.      * @param mixed $shortId
  1311.      * @param mixed $cartId
  1312.      * @return RedirectResponse|Response
  1313.      */
  1314.     public function checkPaypalPaymentAction(ShortId $shortId$cartIdEntityManagerInterface $entityManager)
  1315.     {
  1316.         $decodedId $shortId->decode($cartId);
  1317.         $cart $entityManager->getRepository(Cart::class)->findOneByCartId($decodedId);
  1318.         if ($cart instanceof Cart && $cart->isPaid()) {
  1319.             $response = ['result' => 'ok''redirect' => $this->generateUrl("brulafine_over", ['shortId' => $cartId])];
  1320.         } else {
  1321.             $response = ['result' => 'fail'];
  1322.         }
  1323.         return new JsonResponse($response200);
  1324.     }
  1325.     /**
  1326.      * @Route("/cart/3dspayment/{merkavId}/{transactionId}/3ds", name="brulafine_3dspayment")
  1327.      * @param Request $request
  1328.      * @param mixed $merkavId
  1329.      * @param mixed $transactionId
  1330.      * @return RedirectResponse
  1331.      */
  1332.     public function externalPaymentAction(Request $request$merkavId$transactionIdLoggerInterface $loggerShortId $shortIdEntityManagerInterface $entityManager)
  1333.     {
  1334.         // Stopped for 1 seconde
  1335.         sleep(1);
  1336.         $transactionRepo $entityManager->getRepository(Transaction::class);
  1337.         // First, check transaction:
  1338.         $transaction $transactionRepo->find($transactionId);
  1339.         // If there is no transaction wait a little more
  1340.         if (!$transaction instanceof Transaction) {
  1341.             sleep(3);
  1342.             $transaction $transactionRepo->find($transactionId);
  1343.         }
  1344.         // If there is no transaction wait a little more
  1345.         if (!$transaction instanceof Transaction) {
  1346.             sleep(9);
  1347.             $transaction $transactionRepo->find($transactionId);
  1348.         }
  1349.         if (!$transaction instanceof Transaction) {
  1350.             $this->addFlash('error''flashMessages.site.paymentNotFinalizedMissing');
  1351.             $logger->critical("**3DS ERROR *** Missing transaction in 3DS callback. Data =>  Transaction ID : {$transactionId}, Request : " print_r($requesttrue));
  1352.             return $this->redirectToRoute('brulafine_payment');
  1353.         }
  1354.         // Add the info that the user saw the return page.
  1355.         $transaction->setVisitedReturnPage(true);
  1356.         $entityManager->flush();
  1357.         $cart $transaction->getCart();
  1358.         if (!$cart instanceof Cart) {
  1359.             $logger->critical("**3DS ERROR *** Receiving a callback for a 3ds trx but can't find the cart! Data =>  Transaction ID : {$transactionId}, Request : " print_r($requesttrue));
  1360.             return $this->redirectToRoute('brulafine_payment');
  1361.         }
  1362.         if ($merkavId != $transaction->getTransactionMerkavId()) {
  1363.             $this->addFlash('error''flashMessages.site.paymentNotFinalizedWrongMkvId');
  1364.             $logger->critical("**3DS ERROR *** Wrong transaction id in 3DS callback. Data =>  Transaction ID : {$transactionId}, Request : " print_r($requesttrue));
  1365.             return $this->redirectToRoute('brulafine_payment');
  1366.         }
  1367.         // Check if this is the payment transaction is a bill.
  1368.         if (!$transaction->getUpsellCart() instanceof UpsellCart && Transaction::BILL != $transaction->getTransactionType()) {
  1369.             $this->addFlash('error''flashMessages.site.paymentNotFinalizedWrongType');
  1370.             $logger->error("**3DS ERROR *** Wrong transaction type in 3DS callback. Data =>  Transaction ID : {$transactionId}, Request : " print_r($requesttrue));
  1371.             return $this->redirectToRoute('brulafine_payment');
  1372.             // If there is a payment transaction, make sure that this is with the correct status (rebill for upsell)
  1373.         } elseif ($transaction->getUpsellCart() instanceof UpsellCart && Transaction::REBILL != $transaction->getTransactionType()) {
  1374.             $this->addFlash('error''flashMessages.site.paymentNotFinalizedWrongType');
  1375.             $logger->error("**3DS ERROR *** Wrong transaction type in 3DS callback. Data =>  Transaction ID : {$transactionId}, Request : " print_r($requesttrue));
  1376.             return $this->redirectToRoute('brulafine_over', ['shortId' => $cart->getEncodedId($shortId)]);
  1377.         }
  1378.         // if this transaction is marked as failed or error then no need to wait anything ...
  1379.         if (in_array($transaction->getTransactionStatus(), [Transaction::FAILEDTransaction::ERROR])) {
  1380.             if (!$transaction->getUpsellCart() instanceof UpsellCart) {
  1381.                 $this->addFlash('error''flashMessages.site.paymentNotFinalizedWrongStatus');
  1382.                 return $this->redirectToRoute('brulafine_payment');
  1383.             } elseif ($transaction->getUpsellCart() instanceof UpsellCart) {
  1384.                 $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1385.                 return $this->redirectToRoute('brulafine_over', ['shortId' => $cart->getEncodedId($shortId)]);
  1386.             }
  1387.         }
  1388.         // Starting from here it is possible that we loaded the transaction very fast but it wasn't already updated.
  1389.         // Let's add a timer for a second chance.
  1390.         if (Transaction::OK != $transaction->getTransactionStatus()) {
  1391.             sleep(2);
  1392.         }
  1393.         $entityManager->refresh($transaction);
  1394.         // Again if transaction became failed we stop here.
  1395.         if (in_array($transaction->getTransactionStatus(), [Transaction::FAILEDTransaction::ERROR])) {
  1396.             if (!$transaction->getUpsellCart() instanceof UpsellCart) {
  1397.                 $this->addFlash('error''flashMessages.site.paymentNotFinalizedWrongStatus');
  1398.                 return $this->redirectToRoute('brulafine_payment');
  1399.             } elseif ($transaction->getUpsellCart() instanceof UpsellCart) {
  1400.                 $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1401.                 return $this->redirectToRoute('brulafine_over', ['shortId' => $cart->getEncodedId($shortId)]);
  1402.             }
  1403.         }
  1404.         // if not ok manage the return.
  1405.         if (Transaction::OK != $transaction->getTransactionStatus()) {
  1406.             if (!$transaction->getUpsellCart() instanceof UpsellCart) {
  1407.                 $this->addFlash('error''flashMessages.site.paymentNotFinalizedWrongStatus');
  1408.                 $logger->error("**3DS ERROR *** Wrong transaction status in 3DS callback. Data =>  Transaction ID : {$transactionId}, Request : " print_r($requesttrue));
  1409.                 return $this->redirectToRoute('brulafine_payment');
  1410.             } elseif ($transaction->getUpsellCart() instanceof UpsellCart) {
  1411.                 $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1412.                 $logger->error("**3DS ERROR *** Wrong transaction status in 3DS callback for an upsell purchase. Data =>  Transaction ID : {$transactionId}, Request : " print_r($requesttrue));
  1413.                 return $this->redirectToRoute('brulafine_over', ['shortId' => $cart->getEncodedId($shortId)]);
  1414.             } else {
  1415.                 $logger->critical("Unknow status for a return in the 3ds system. {$transaction->getTransactionId()} - status : {$transaction->getTransactionStatus()}");
  1416.                 return $this->redirectToRoute('brulafine_payment');
  1417.             }
  1418.         }
  1419.         // if this was an upsell we add the info as flash.
  1420.         if ($transaction->getUpsellCart() instanceof UpsellCart) {
  1421.             $this->addFlash('info''flashMessages.site.additionnalPurchaseOK');
  1422.         }
  1423.         return $this->redirectToRoute('brulafine_over', ['shortId' => $cart->getEncodedId($shortId)]);
  1424.     }
  1425.     /**
  1426.      * @Route("/cart/over/{shortId}", name="brulafine_over",requirements={"shortId" = "[\w-]+"})
  1427.      * @param Request $request
  1428.      * @param PackManager $packFactory
  1429.      * @param LoggerInterface $logger
  1430.      * @param SiteManager $siteManager
  1431.      * @param CartManager $cartFactory
  1432.      * @param SessionInterface $session
  1433.      * @param Packages $package
  1434.      * @param ABTestManager $ABTestManager
  1435.      * @param FacebookApiEventsManager $facebookApiEventsManager
  1436.      * @param EventDispatcherInterface $eventDispatcher
  1437.      * @param EntityManagerInterface $entityManager
  1438.      * @param ShortId $shortIdGenerator
  1439.      * @param EmailManager $emailManager
  1440.      * @param null|string $shortId
  1441.      * @return RedirectResponse|Response
  1442.      * @throws Exception
  1443.      */
  1444.     public function overAction(
  1445.         Request $request,
  1446.         PackManager $packFactory,
  1447.         LoggerInterface $logger,
  1448.         SiteManager $siteManager,
  1449.         CartManager $cartFactory,
  1450.         SessionInterface $session,
  1451.         Packages $package,
  1452.         ABTestManager $ABTestManager,
  1453.         FacebookApiEventsManager $facebookApiEventsManager,
  1454.         EventDispatcherInterface $eventDispatcher,
  1455.         EntityManagerInterface $entityManager,
  1456.         ShortId $shortIdGenerator,
  1457.         EmailManager $emailManager,
  1458.         string $shortId null
  1459.     ): RedirectResponse|Response {
  1460.         $displayConversionTag $siteManager->canDisplayConversionTag();
  1461.         $setup $this->getSetup();
  1462.         $locale $request->getLocale();
  1463.         try {
  1464.             $cartId $shortIdGenerator->decode($shortId);
  1465.         } catch (\Throwable $e) {
  1466.             $logger->critical("Receiving wrong cart id for cart over page : {$shortId} - can't process. -- {$request->headers->get('referer')} -- ");
  1467.             return $this->redirectToRoute('brulafine_show_packs');
  1468.         }
  1469.         $user $setup->getUser();
  1470.         if (!$user instanceof User) {
  1471.             $user $entityManager->getRepository(User::class)->findOneBy(['id' => $request->getSession()->get(User::GUEST_USER_SESSION_KEY)]);
  1472.         }
  1473.         // Si le client arrive avec un cart en train d'etre paye
  1474.         $cart $entityManager->getRepository(Cart::class)->findOneBy(['cartId' => $cartId'user' => $user]);
  1475.         if (!$cart instanceof Cart) {
  1476.             return $this->redirectToRoute('brulafine_show_packs');
  1477.         }
  1478.         if (Cart::STATE_PENDING_PAYMENT == $cart->getCartState()) {
  1479.             return $this->redirectToRoute('brulafine_payment');
  1480.         }
  1481.         if ($cart->isWaitingBankTransfer()) {
  1482.             // on vire le cart de la session ... il n'y a plus de cart
  1483.             $this->getCartFactory()->removeCartFromSession();
  1484.             $response $this->render($this->getTemplatesDir() . '/Default/bank-transfert.html.twig', [
  1485.                 'cart' => $cart,
  1486.                 'cartTotal' => $this->getCartFactory()->computeCartTotal($cart),
  1487.                 'site' => $setup->getSite(),
  1488.             ]);
  1489.             return $this->appendCookie($response$setup->getCookie());
  1490.         }
  1491.         $transaction $entityManager->getRepository(Transaction::class)->findOneBy(['cart' => $cart], ['transactionId' => 'desc']);
  1492.         if (!$transaction instanceof Transaction || Transaction::ERROR == $transaction->getTransactionStatus()) {
  1493.             return $this->redirectToRoute('brulafine_payment');
  1494.         }
  1495.         // on vire le cart de la session ... il n'y a plus de cart
  1496.         $this->getCartFactory()->removeCartFromSession();
  1497.         //on regarde l'etat du cart
  1498.         //si le cart a deja ete envoye on a rien a faire ici
  1499.         if (!$cart->isInReview()) {
  1500.             return $this->redirectToRoute('brulafine_user_commandes');
  1501.         }
  1502.         $user $cart->getUser();
  1503.         $upsellProducts = [];
  1504.         if (!$cart->getPaymentTransaction() instanceof Transaction) {
  1505.             $logger->critical("We have a cart in the over action that is not paid. {$cart->getCartId()} with the status {$cart->getCartState()}");
  1506.         }
  1507.         if ($cart->getSite()->hasUpsells() && $cart->canAddUpsells() && $siteManager->localeHasUpsells($locale)) {
  1508.             $upsellPacks $packFactory->getUpsellPacks();
  1509.             $upsellProducts $ABTestManager->getPacksForTracking($setup->getTracking(), $upsellPacks);
  1510.             if (strtoupper($cart->getCartAddress()->getCountry()) == "BE") {
  1511.                 $filteredUpsellProducts = [];
  1512.                 $notAllowedUpsellPacks = ['Dormalis''Pack_Huile_Minceur'];
  1513.                 /** @var SitePackTemplate $upsellProduct */
  1514.                 foreach ($upsellProducts as $upsellProduct) {
  1515.                     if (!in_array($upsellProduct->getPackTemplate()->getPackTemplateName(), $notAllowedUpsellPacks)) {
  1516.                         $filteredUpsellProducts[] = $upsellProduct;
  1517.                     }
  1518.                 }
  1519.                 $upsellProducts $filteredUpsellProducts;
  1520.             }
  1521.         }
  1522.         $preUpsellPack null;
  1523.         if ($cart->getSite()->hasPreUpsells() && $cart->canAddUpsells()) {
  1524.             $preUpsellPack $cartFactory->getLinkedPreUpsellFromCart($cart);
  1525.         }
  1526.         // We enter into the upsell area, yeah !! :)
  1527.         $purchaseSuccess false;
  1528.         if ($request->getMethod() === "POST" && !empty($upsellProducts) && $request->request->get('buyUpsell')) {
  1529.             // here we buy the new stuff :)
  1530.             $upsellCart = new UpsellCart($cart);
  1531.             $entityManager->persist($upsellCart);
  1532.             $selectedProduct null;
  1533.             $selectedId = (int) $request->request->get('id');
  1534.             $selectedQuantity = (int) $request->request->get('quantity');
  1535.             foreach ($upsellProducts as $upsellProduct) {
  1536.                 if ($upsellProduct->getSitePackTemplateId() === $selectedId) {
  1537.                     $selectedProduct $upsellProduct;
  1538.                     break;
  1539.                 }
  1540.             }
  1541.             if ($selectedQuantity UpsellCart::MAX_SINGLE_ITEM) {
  1542.                 $selectedQuantity 10;
  1543.             }
  1544.             if ($selectedQuantity 0) {
  1545.                 $selectedQuantity 1;
  1546.             }
  1547.             if ($selectedProduct instanceof SitePackTemplate) {
  1548.                 $upsellPack $packFactory->makeUpsellPackFromTemplate($upsellProduct->getPackTemplate(), $cart->getTracking());
  1549.                 $upsellPack->updateQuantity($selectedQuantity);
  1550.                 $upsellCart->addUpsellPack($upsellPack);
  1551.                 $entityManager->persist($upsellPack);
  1552.                 $entityManager->flush();
  1553.                 // ici on tente l'achat
  1554.                 $purchase = new Purchase();
  1555.                 //$purchase->setPaymentMethod(Purchase::PAYMENT_3DS);
  1556.                 $bypassPayment false;
  1557.                 $userPayment = new CardPayment($request->getClientIp(), $request->headers->get('User-Agent'));
  1558.                 //**************
  1559.                 try {
  1560.                     $this->getBillingFactory()->processUpsellCart($upsellCart$userPayment$purchase);
  1561.                     $cartTotal $cartFactory->computeCartTotal($upsellCart);
  1562.                     $upsellCart->setUpsellCartTotalAmount($cartTotal['packGrandTotal']);
  1563.                     $entityManager->flush();
  1564.                     $this->addFlash('upsell_conversion_tag''show');
  1565.                     $session->set('justPurchasedUpsell'true);
  1566.                     if (Purchase::STATUS_SUCCESS === $purchase->getStatus()) {
  1567.                         $this->addFlash('info''flashMessages.site.additionnalPurchaseOK');
  1568.                         $request->getSession()->set(self::UPSELL_PURCHASE_SUCCESStrue);
  1569.                         return $this->redirectToRoute('brulafine_over', ['shortId' => $shortId]);
  1570.                     }
  1571.                     if (Purchase::STATUS_FAILED === $purchase->getStatus()) {
  1572.                         $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1573.                         return $this->redirectToRoute('brulafine_over', ['shortId' => $shortId]);
  1574.                     }
  1575.                     if (Purchase::PAYMENT_3DS === $purchase->getPaymentMethod()) {
  1576.                         $code = new CodeHtml3DSLog();
  1577.                         $code->setDate(new \DateTime());
  1578.                         $code->setCode($purchase->getMetaData()['code']);
  1579.                         $code->setTransaction($purchase->getPreviousTransaction());
  1580.                         $entityManager->persist($code);
  1581.                         $entityManager->flush();
  1582.                         return $this->render($this->getTemplatesDir() . '/Default/display-html-code.html.twig', [
  1583.                             'code' => $purchase->getMetaData()['code'],
  1584.                         ]);
  1585.                     }
  1586.                     throw new \RuntimeException(sprintf('Undefined %s Purchase method'$purchase->getPaymentMethod()));
  1587.                 } catch (Throwable $e) {
  1588.                     $message 'Une erreur est survenue apres transaction.' PHP_EOL
  1589.                         'CLIENT EMAIL = ' $user->getUsername() . PHP_EOL
  1590.                         'CART ID = ' $cart->getCartId() . PHP_EOL
  1591.                         'ERROR TYPE = ' get_class($e) . PHP_EOL
  1592.                         'ERROR CODE = ' $e->getCode() . PHP_EOL
  1593.                         'ERROR Message = ' $e->getMessage() . PHP_EOL
  1594.                         'ERROR TRACE = ' $e->getTraceAsString() . PHP_EOL;
  1595.                     $emailManager->sendPaymentAlert("[{$cartFactory->siteManager->getCurrentSite()->getSiteName()}] payment error after transaction succeeded"$message);
  1596.                     $logger->error($e->getMessage());
  1597.                     $logger->critical("[{$cartFactory->siteManager->getCurrentSite()->getSiteName()}] payment error after transaction succeeded => " $message);
  1598.                     $this->addFlash('conversion_tag''show');
  1599.                     $session->set('justPurchased'true);
  1600.                     $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1601.                     return $this->redirectToRoute('brulafine_over', ['shortId' => $shortId]);
  1602.                 }
  1603.             }
  1604.         }
  1605.         if ($request->getMethod() === "POST" && $request->request->get('justRejectPreUpsell')) {
  1606.             $cartFactory->addNewAction($cartCartAction::REFUSED_PREUPSELL);
  1607.         }
  1608.         // Here we enter in PreUpsell :)
  1609.         if ($request->getMethod() === "POST" && $request->request->get('buyPreUpsell') && null != $preUpsellPack) {
  1610.             // here we buy the new stuff :)
  1611.             $upsellCart = new UpsellCart($cart);
  1612.             $entityManager->persist($upsellCart);
  1613.             if ($preUpsellPack instanceof SitePackTemplate) {
  1614.                 $upsellPack $packFactory->makeUpsellPackFromTemplate($preUpsellPack->getPackTemplate(), $cart->getTracking());
  1615.                 $upsellCart->addUpsellPack($upsellPack);
  1616.                 $upsellCart->setIsPreUpsell(true);
  1617.                 $entityManager->persist($upsellPack);
  1618.                 $entityManager->flush();
  1619.                 // ici on tente l'achat
  1620.                 $purchase = new Purchase();
  1621.                 //$purchase->setPaymentMethod(Purchase::PAYMENT_3DS);
  1622.                 $bypassPayment false;
  1623.                 $userPayment = new CardPayment($request->getClientIp(), $request->headers->get('User-Agent'));
  1624.                 //**************
  1625.                 try {
  1626.                     $this->getBillingFactory()->processUpsellCart($upsellCart$userPayment$purchase);
  1627.                     $cartTotal $cartFactory->computeCartTotal($upsellCart);
  1628.                     $upsellCart->setUpsellCartTotalAmount($cartTotal['packGrandTotal']);
  1629.                     $entityManager->flush();
  1630.                     $this->addFlash('upsell_conversion_tag''show');
  1631.                     if (Purchase::STATUS_SUCCESS === $purchase->getStatus()) {
  1632.                         $this->addFlash('info''flashMessages.site.additionnalPurchaseOK');
  1633.                         $request->getSession()->set(self::UPSELL_PURCHASE_SUCCESStrue);
  1634.                         return $this->redirectToRoute('brulafine_over', ['shortId' => $shortId]);
  1635.                     }
  1636.                     if (Purchase::STATUS_FAILED === $purchase->getStatus()) {
  1637.                         $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1638.                         return $this->redirectToRoute('brulafine_over', ['shortId' => $shortId]);
  1639.                     }
  1640.                     if (Purchase::PAYMENT_3DS === $purchase->getPaymentMethod()) {
  1641.                         $code = new CodeHtml3DSLog();
  1642.                         $code->setDate(new \DateTime());
  1643.                         $code->setCode($purchase->getMetaData()['code']);
  1644.                         $code->setTransaction($purchase->getPreviousTransaction());
  1645.                         $entityManager->persist($code);
  1646.                         $entityManager->flush();
  1647.                         return $this->render($this->getTemplatesDir() . '/Default/display-html-code.html.twig', [
  1648.                             'code' => $purchase->getMetaData()['code'],
  1649.                         ]);
  1650.                     }
  1651.                     throw new \RuntimeException(sprintf('Undefined %s Purchase method'$purchase->getPaymentMethod()));
  1652.                 } catch (Throwable $e) {
  1653.                     $message 'Une erreur est survenue apres transaction.' PHP_EOL
  1654.                         'CLIENT EMAIL = ' $user->getUsername() . PHP_EOL
  1655.                         'CART ID = ' $cart->getCartId() . PHP_EOL
  1656.                         'ERROR TYPE = ' get_class($e) . PHP_EOL
  1657.                         'ERROR CODE = ' $e->getCode() . PHP_EOL
  1658.                         'ERROR Message = ' $e->getMessage() . PHP_EOL
  1659.                         'ERROR TRACE = ' $e->getTraceAsString() . PHP_EOL;
  1660.                     $emailManager->sendPaymentAlert("[{$cartFactory->siteManager->getCurrentSite()->getSiteName()}] payment error after transaction succeeded"$message);
  1661.                     $logger->error($e->getMessage());
  1662.                     $logger->critical("[{$cartFactory->siteManager->getCurrentSite()->getSiteName()}] payment error after transaction succeeded => " $message);
  1663.                     $this->addFlash('conversion_tag''show');
  1664.                     $session->set('justPurchased'true);
  1665.                     $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1666.                     return $this->redirectToRoute('brulafine_over', ['shortId' => $shortId]);
  1667.                 }
  1668.             }
  1669.         }
  1670.         /** @var SitePackTemplate $sitePackTemplate */
  1671.         $sitePackTemplate $cartFactory->getSitePackTemplateForCart($cart);
  1672.         if ($cartFactory->cartIsEligibleForPreUpsell($cart) && $cart->canAddUpsells() && !$sitePackTemplate->isPreUpsell()) {
  1673.             $template $this->getTemplatesDir() . '/Default/over_pre_upsale.html.twig';
  1674.         } elseif (!$sitePackTemplate->isPreUpsell() && !$sitePackTemplate->isUpsell() && count($upsellProducts) !== 0) {
  1675.             $template $this->getTemplatesDir() . '/Default/over_upsell.html.twig';
  1676.         } else {
  1677.             $template $this->getTemplatesDir() . '/Default/over.html.twig';
  1678.         }
  1679.         $upsellProductsArrayForTwig = [];
  1680.         $upsellProductsArrayForTwigWithKeys = [];
  1681.         foreach ($upsellProducts as $upsellProduct) {
  1682.             /** @var PackTemplate $packTemplate */
  1683.             $packTemplate $upsellProduct->getPackTemplate();
  1684.             $options $packTemplate->getPackTemplateOptions();
  1685.             $title $options['title'][$locale] ?? '';
  1686.             $product = [
  1687.                 'id' => $upsellProduct->getSitePackTemplateId(),
  1688.                 'name' => $packTemplate->getPackTemplateName(),
  1689.                 'title' => $title,
  1690.                 'desc_short' => $options['short_desc'][$locale] ?? '',
  1691.                 'description_medium' => $options['medium_desc'][$locale] ?? '',
  1692.                 'reduction_percent' => $options['reduc_percent'],
  1693.                 'price' => $options['normal_price'],
  1694.                 'reducted_price' => $options['reduc_price'],
  1695.                 'quantity' => 1,
  1696.                 'image' => $package->getUrl($options['image_link'][$locale] ?? ''),
  1697.                 'image_large' => $package->getUrl($options['image_large_link'][$locale] ?? ''),
  1698.                 'category' => $options['category'][$locale] ?? '',
  1699.                 'category_color' => $options['category_color'],
  1700.             ];
  1701.             if (isset($options['suggest_pack'])) {
  1702.                 $product['pack'] = $options['suggest_pack'];
  1703.                 $product['pack_modal_title'] = $options['modal_title'][$locale] ?? '';
  1704.             }
  1705.             $upsellProductsArrayForTwig[] = $product;
  1706.             $upsellProductsArrayForTwigWithKeys[$product['name']] = $product;
  1707.         }
  1708.         // le paiement a ete effectue correctement
  1709.         $cartTotal $this->getCartFactory()->computeCartTotal($cart);
  1710.         /** @var CartCreditNote $cartCreditNote */
  1711.         $cartCreditNote $cart->getCreditNotes()[0];
  1712.         if ($cartTotal['creditNoteAmount'] && !$cartCreditNote->isUsed()) {
  1713.             $event = new CartCreditNoteUsedEvent($cart$cartTotal);
  1714.             $eventDispatcher->dispatch($eventCartSubscriber::CART_CREDIT_NOTE_USED);
  1715.         }
  1716.         $electronicProductShipping $entityManager
  1717.             ->getRepository(ElectronicProductShipping::class)
  1718.             ->findOneBy(['user' => $user'status' => ElectronicProductShipping::ACTIVATED]);
  1719.         if (null !== $electronicProductShipping) {
  1720.             $coachingLink true;
  1721.         } else {
  1722.             $coachingLink false;
  1723.         }
  1724.         $cartLockTime $cart->getCartLockedAt();
  1725.         $now = new \DateTime();
  1726.         if (!$cartLockTime instanceof \DateTime) {
  1727.             $cartLockDelay $siteManager->getYamlConfigParameter("frontEnd")['upsells']['delayBeforeCartLock'] ?? "PT30M";
  1728.             $cartLockTime $now->add(new \DateInterval($cartLockDelay));
  1729.         }
  1730.         $upsellTime $cartLockTime->diff($now);
  1731.         if (!$upsellTime->&& !$upsellTime->s) {
  1732.             $upsellTime = new \DateInterval($cartLockDelay);
  1733.         }
  1734.         $upsellTime = ['mins' => $upsellTime->i'sec' => $upsellTime->s];
  1735.         $justPurchasedUpsell false;
  1736.         if ($request->getSession()->has(self::UPSELL_PURCHASE_SUCCESS) && true === $request->getSession()->get(self::UPSELL_PURCHASE_SUCCESS)) {
  1737.             $request->getSession()->remove(self::UPSELL_PURCHASE_SUCCESS);
  1738.             $justPurchasedUpsell true;
  1739.         }
  1740.         $defaultPacks $this->getPackFactory()->getDefaultProposedPacks($setup->getSite());
  1741.         $defaultProposedPack $ABTestManager->getPacksForTracking($setup->getTracking(), $defaultPacks);
  1742.         $facebookApiEventsManager->createEvent(FacebookApiEventsManager::PURCHASE$cart$setup->getTracking());
  1743.         $response $this->render($template, [
  1744.             'cart' => $cart,
  1745.             'cartTotal' => $cartTotal,
  1746.             'cartShortId' => $shortIdGenerator->encode($cart->getCartId()),
  1747.             'espace_link' => $coachingLink,
  1748.             'defaultProposedPacks' => $defaultProposedPack,
  1749.             'tracking' => $setup->getTracking(),
  1750.             'site' => $setup->getSite(),
  1751.             'displayConversionTag' => $displayConversionTag,
  1752.             'upsellProducts' => $upsellProducts,
  1753.             'upsellProductsArray' => $upsellProductsArrayForTwigWithKeys,
  1754.             'purchaseSuccess' => $purchaseSuccess,
  1755.             'upsellProductsJs' => json_encode($upsellProductsArrayForTwig),
  1756.             'lastFour' => $cart->getPaymentTransaction()->getPaymentToken() instanceof PaymentToken $cart->getPaymentTransaction()->getPaymentToken()->getLastFour() : PaymentToken::DEFAULT_EMPTY_LAST_FOUR,
  1757.             'upsellTime' => $upsellTime,
  1758.             'justPurchasedUpsell' => $justPurchasedUpsell,
  1759.             'preUpsellPack' => $preUpsellPack
  1760.         ]);
  1761.         return $this->appendCookie($response$setup->getCookie());
  1762.     }
  1763.     /**
  1764.      * @Route("/cart/confirm", name="brulafine_confirm")
  1765.      * @return Response
  1766.      * @throws Exception
  1767.      */
  1768.     public function confirmAction(ABTestManager $abTestManager)
  1769.     {
  1770.         $setup $this->getSetup();
  1771.         //get current cart
  1772.         $currentCart $setup->getCart();
  1773.         //if cart is empty fill it :)
  1774.         if (!$currentCart) {
  1775.             return $this->redirectToRoute('brulafine_show_packs');
  1776.         }
  1777.         //if the order is in more than 30 minutes don`t show confirm page
  1778.         if (!$this->getCartFactory()->hasOrderInDelay($setup->getUser())) {
  1779.             return $this->redirectToRoute('brulafine_show_packs');
  1780.         }
  1781.         //get last paid Cart
  1782.         /** @var Cart $lastPaidCart */
  1783.         $lastPaidCart $this->getCartFactory()->getLastPaidCart($setup->getUser());
  1784.         $defaultPacks $this->getPackFactory()->getDefaultProposedPacks($setup->getSite());
  1785.         $defaultProposedPack $abTestManager->getPacksForTracking($setup->getTracking(), $defaultPacks);
  1786.         $response $this->render($this->getTemplatesDir() . '/Default/confirm.html.twig', [
  1787.             'cart' => $currentCart,
  1788.             'currentCartTotal' => $setup->getCartTotal(),
  1789.             'lastPaidCart' => $lastPaidCart,
  1790.             'lastPaidCartDate' => $lastPaidCart->getPaymentTransaction()->getTransactionStamp(),
  1791.             'lastPaidCartTotal' => $this->getCartFactory()->computeCartTotal($lastPaidCart),
  1792.             'defaultProposedPacks' => $defaultProposedPack,
  1793.             'tracking' => $setup->getTracking(),
  1794.             'site' => $setup->getSite(),
  1795.         ]);
  1796.         return $this->appendCookie($response$setup->getCookie());
  1797.     }
  1798.     /**
  1799.      * @Route("/offers/{offer}", name="brulafine_offers")
  1800.      * @param Request $request
  1801.      * @param LoggerInterface $logger
  1802.      * @param SiteManager $siteManager
  1803.      * @param CartManager $cartFactory
  1804.      * @param SessionInterface $session
  1805.      * @param Packages $package
  1806.      * @param EntityManagerInterface $entityManager
  1807.      * @param ShortId $shortIdTool
  1808.      * @param $offer
  1809.      * @return RedirectResponse|Response
  1810.      * @throws Exception
  1811.      */
  1812.     public function offersAction(
  1813.         Request $request,
  1814.         LoggerInterface $logger,
  1815.         SiteManager $siteManager,
  1816.         CartManager $cartFactory,
  1817.         SessionInterface $session,
  1818.         Packages $package,
  1819.         EntityManagerInterface $entityManager,
  1820.         ShortId $shortIdTool,
  1821.         EmailManager $emailManager,
  1822.         $offer
  1823.     ) {
  1824. //        $displayConversionTag = $siteManager->canDisplayConversionTag();
  1825.         $setup $this->getSetup();
  1826.         $environment $this->getParameter("kernel.environment");
  1827.         if ($request->query->get('3ds') || ($siteManager->getYamlConfigParameter('site_force_3ds') && !in_array($environment, ['test''dev']))) {
  1828.             $session->set('force_3ds'true);
  1829.         }
  1830.         // we need to know which offer to load.
  1831.         if (null == $offer || !in_array($offerCartManager::$possibleOffers)) {
  1832.             return $this->redirectToRoute('brulafine_show_packs');
  1833.         }
  1834.         // load the user - from the system or the session (for Guest users).
  1835.         $user $setup->getUser();
  1836.         if (!$user instanceof User) {
  1837.             $user $entityManager->getRepository(User::class)->findOneBy(['id' => $request->getSession()->get(User::GUEST_USER_SESSION_KEY)]);
  1838.         }
  1839.         // we must have a user here.
  1840.         if (!$user instanceof User) {
  1841.             return $this->redirectToRoute('brulafine_show_packs');
  1842.         }
  1843.         // get last order
  1844.         $lastOrder $user->getLastOrder();
  1845.         if (!$lastOrder instanceof Cart) {
  1846.             return $this->redirectToRoute('brulafine_show_packs');
  1847.         }
  1848.         // if the main pack is preupsell or upsell we skip it
  1849.         /** @var SitePackTemplate $sitePackTemplate */
  1850.         $sitePackTemplate $cartFactory->getSitePackTemplateForCart($lastOrder);
  1851.         if (($offer == CartManager::OFFER_PREUPSELL && $sitePackTemplate->isPreUpsell()) || ($offer == CartManager::OFFER_UPSELL && $sitePackTemplate->isUpsell())) {
  1852.             return $this->redirectToRoute('brulafine_show_packs');
  1853.         }
  1854.         // if the last cart is not eligible for PreUpsells (Custom packs for example) we redirect to upsell offer
  1855.         if (!$cartFactory->cartIsEligibleForPreUpsell($lastOrder) && CartManager::OFFER_PREUPSELL == $offer) {
  1856.             return $this->redirectToRoute('brulafine_offers', ["offer" => CartManager::OFFER_UPSELL]);
  1857.         }
  1858.         // use the address from the last order.
  1859.         $cartAddress $lastOrder->getCartAddress();
  1860.         $duplicateCartAddress = clone $cartAddress;
  1861.         $purchaseSuccess false;
  1862.         // get the offer data
  1863.         $offerData = match ($offer) {
  1864.             CartManager::OFFER_UPSELL => $cartFactory->getUpsellOfferData($lastOrder$setup$package$request),
  1865.             CartManager::OFFER_PREUPSELL => $cartFactory->getPreUpsellOfferData($lastOrder$setup),
  1866.             default => [],
  1867.         };
  1868.         $template $this->getTemplatesDir() . '/Default/' $offerData['template'];
  1869.         $packForCart $offerData['packForCart'];
  1870.         // create offer cart to be able to calculate the shipping.
  1871.         $offerCart null;
  1872.         if ($offerData['createCart']) {
  1873.             $cartCreatedForLastOrderSessionName 'offer["'.$offer.'"]["' $packForCart->getPackTemplateId() . '"]CartCreatedForLastOrder';
  1874.             if ($request->getSession()->get($cartCreatedForLastOrderSessionName) != $lastOrder->getCartId()) {
  1875.                 $offerCart $cartFactory->makeCartFromPackTemplate($packForCart$lastOrder->getSite(), $user->getTracking(), $lastOrder->getAffiliate(), [], $user$duplicateCartAddress);
  1876.                 $offerCart->setCartState(Cart::STATE_ADDRESS_ASSIGNED);
  1877.                 $offerCart->setShippingRule($lastOrder->getShippingRule());
  1878.                 $offerCart->setPickUpPoint($lastOrder->getPickUpPoint());
  1879.                 $offerCart->setCartShippingCountry($lastOrder->getCartShippingCountry());
  1880.                 $offerCart->setCartBillingType(Cart::BILLING_TYPE_CREDITCARD);
  1881.                 $entityManager->flush();
  1882.                 $request->getSession()->set($cartCreatedForLastOrderSessionName$lastOrder->getCartId());
  1883.                 $request->getSession()->set('offer["'.$offer.'"]pack["'.$packForCart->getPackTemplateId().'"]CartId'$offerCart->getCartId());
  1884.             }
  1885.         }
  1886.         // we load the cart from the db by session cart id. Its because on upsell offer we create the cart after ajax request.
  1887.         if (null == $offerCart && $packForCart) {
  1888.             $offerCart $entityManager->getRepository(Cart::class)->findOneBy(['cartId' => $request->getSession()->get('offer["'.$offer.'"]pack["'.$packForCart->getPackTemplateId().'"]CartId')]);
  1889.         }
  1890.         // we update the quantity of the selected pack.
  1891.         if ($request->isXmlHttpRequest() && CartManager::OFFER_UPSELL == $offer) {
  1892.             $cartFactory->updateOfferCartProductQuantity($offerCart$request);
  1893.             //update cart total.
  1894.             $cartTotalForNewCart $cartFactory->computeCartTotal($offerCart);
  1895.             //return cart total to update data in the front end.
  1896.             return new JsonResponse($cartTotalForNewCart200);
  1897.         }
  1898.         // add new action for the cart - justRejectPreUpsell
  1899.         // users with rejected actions, we dont send them emails for the offers
  1900.         if ($request->getMethod() === "POST" && $request->request->get('justRejectPreUpsell')) {
  1901.             $cartFactory->addNewAction($lastOrderCartAction::REFUSED_PREUPSELL);
  1902.             return $this->redirectToRoute('brulafine_offers', ["offer" => CartManager::OFFER_UPSELL]);
  1903.         }
  1904.         // Here we buy the Offer :)
  1905.         if ($request->getMethod() === "POST" &&
  1906.             ($request->request->get('buyPreUpsell') || $request->request->get('buyUpsell'))
  1907.         ) {
  1908.             $purchase = new Purchase();
  1909.             $bypassPayment false;
  1910.             $userPayment = new CardPayment($user->getUserIp(), $user->getUserAgent());
  1911.             //**************
  1912.             try {
  1913.                 $this->getBillingFactory()->processCart($offerCart$offerCart->getSite(), $offerCart->getUser(), $userPayment$purchasetrue);
  1914.                 $this->addFlash('upsell_conversion_tag''show');
  1915.                 if (Purchase::STATUS_SUCCESS === $purchase->getStatus()) {
  1916.                     $this->addFlash('info''flashMessages.site.offerPurchaseOK');
  1917.                     $request->getSession()->set(self::UPSELL_PURCHASE_SUCCESStrue);
  1918.                     return $this->redirectToRoute(
  1919.                         'brulafine_over',
  1920.                         [
  1921.                             'shortId' => $shortIdTool->encode($offerCart->getCartId())
  1922.                         ]
  1923.                     );
  1924.                 }
  1925.                 if (Purchase::STATUS_FAILED === $purchase->getStatus()) {
  1926.                     $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1927.                     return $this->redirectToRoute(
  1928.                         'brulafine_over',
  1929.                         [
  1930.                             'shortId' => $shortIdTool->encode($offerCart->getCartId())
  1931.                         ]
  1932.                     );
  1933.                 }
  1934.                 if (Purchase::PAYMENT_3DS === $purchase->getPaymentMethod()) {
  1935.                     $code = new CodeHtml3DSLog();
  1936.                     $code->setDate(new \DateTime());
  1937.                     $code->setCode($purchase->getMetaData()['code']);
  1938.                     $code->setTransaction($purchase->getPreviousTransaction());
  1939.                     $entityManager->persist($code);
  1940.                     $entityManager->flush();
  1941.                     return $this->render($this->getTemplatesDir() . '/Default/display-html-code.html.twig', [
  1942.                         'code' => $purchase->getMetaData()['code'],
  1943.                     ]);
  1944.                 }
  1945.                 throw new \RuntimeException(sprintf('Undefined %s Purchase method'$purchase->getPaymentMethod()));
  1946.             } catch (Throwable $e) {
  1947.                 $message 'Une erreur est survenue apres transaction.' PHP_EOL
  1948.                     'CLIENT EMAIL = ' $user->getUsername() . PHP_EOL
  1949.                     'CART ID = ' $lastOrder->getCartId() . PHP_EOL
  1950.                     'ERROR TYPE = ' get_class($e) . PHP_EOL
  1951.                     'ERROR CODE = ' $e->getCode() . PHP_EOL
  1952.                     'ERROR Message = ' $e->getMessage() . PHP_EOL
  1953.                     'ERROR TRACE = ' $e->getTraceAsString() . PHP_EOL;
  1954.                 $emailManager->sendPaymentAlert("[{$cartFactory->siteManager->getCurrentSite()->getSiteName()}] payment error after transaction succeeded"$message);
  1955.                 $logger->error($e->getMessage());
  1956.                 $logger->critical("[{$cartFactory->siteManager->getCurrentSite()->getSiteName()}] payment error after transaction succeeded => " $message);
  1957.                 $this->addFlash('conversion_tag''show');
  1958.                 $session->set('justPurchased'true);
  1959.                 $this->addFlash('info''flashMessages.site.additionnalPurchaseNOTOK');
  1960.                 return $this->redirectToRoute('brulafine_offers', ['offer' => $offer]);
  1961.             }
  1962.         }
  1963.         // after the payment we calculate the cart total of the last order
  1964.         $cartTotal $cartFactory->computeCartTotal($lastOrder);
  1965.         $justPurchasedUpsell false;
  1966.         if ($request->getSession()->has(self::UPSELL_PURCHASE_SUCCESS)
  1967.             && true === $request->getSession()->get(self::UPSELL_PURCHASE_SUCCESS)) {
  1968.             $request->getSession()->remove(self::UPSELL_PURCHASE_SUCCESS);
  1969.             $justPurchasedUpsell true;
  1970.         }
  1971.         $newCartTotal null;
  1972.         if ($offerCart) {
  1973.             $newCartTotal $cartFactory->computeCartTotal($offerCart);
  1974.         }
  1975.         $basicTemplateParams = [
  1976.             'cart' => $lastOrder,
  1977.             'cartTotal' => $cartTotal,
  1978.             'newCartTotal' => $newCartTotal,
  1979.             'cartShortId' => $offerCart $shortIdTool->encode($offerCart->getCartId()) : '',
  1980.             'offer' => $offer,
  1981.             'tracking' => $setup->getTracking(),
  1982.             'purchaseSuccess' => $purchaseSuccess,
  1983.             'justPurchasedUpsell' => $justPurchasedUpsell,
  1984.         ];
  1985.         $templateParams array_merge($basicTemplateParams$offerData['templateData']);
  1986.         $response $this->render($template$templateParams);
  1987.         return $this->appendCookie($response$setup->getCookie());
  1988.     }
  1989.     /**
  1990.      * If the client got two orders he needs to confirm one or the other.
  1991.      * Depending on the one we receive, we cancel it.
  1992.      * @Route("/cart/confirm/{shortId}", name="brulafine_cancel_cart",requirements={"shortId" = "[\w-]+"})
  1993.      * @param null|string $shortId
  1994.      * @return RedirectResponse
  1995.      */
  1996.     public function cancelCartAction(string $shortId nullEntityManagerInterface $entityManagerShortId $shortIdGenerator)
  1997.     {
  1998.         $setup $this->getSetup();
  1999.         $cartId $shortIdGenerator->decode($shortId);
  2000.         $redirect 'brulafine_home';
  2001.         //get cart
  2002.         /** @var Cart $cart */
  2003.         $cart $entityManager->getRepository(Cart::class)->findOneBy(['cartId' => $cartId'user' => $setup->getUser()]);
  2004.         if ($cart instanceof Cart) {
  2005.             // the cart is the current one that he didn't pay.
  2006.             if ($setup->getCart() instanceof Cart && $setup->getCart()->getCartId() === $cart->getCartId() && !$cart->isPurchased()) {
  2007.                 $this->getCartFactory()->cleanUpCurrentCart($setup->getCart());
  2008.                 $this->addFlash('info'"flashMessages.site.emptyCart");
  2009.             } elseif ($cart->isPaidButNotShipped()) {
  2010.                 // request cancellation of the order
  2011.                 if ($this->getCartFactory()->transitState($cart"requestCancelationFromClient")) {
  2012.                     $this->addFlash('info'"flashMessages.site.previouseOrderCanceled");
  2013.                     $redirect 'brulafine_payment';
  2014.                     $entityManager->flush();
  2015.                 } else {
  2016.                     // normally shouldn't happen, except if the status of the cart has changed before he clicks
  2017.                     $this->addFlash('error'"flashMessages.site.errorOccuredTryAgain");
  2018.                 }
  2019.             }
  2020.         }
  2021.         return $this->redirectToRoute($redirect);
  2022.     }
  2023.     /**
  2024.      * @Route("/cart/secure/payment", name="brulafine_initiate_3ds_payment")
  2025.      * @return Response
  2026.      * @throws Exception
  2027.      */
  2028.     public function generate3DSiframe(SessionInterface $session)
  2029.     {
  2030.         $code $session->get(UserPayment::SESSION_3DS_CODE);
  2031.         $session->remove(UserPayment::SESSION_3DS_CODE);
  2032.         return $this->render(
  2033.             $this->getTemplatesDir() . '/Default/3ds-iframe.html.twig',
  2034.             [
  2035.                 'code' => $code
  2036.             ]
  2037.         );
  2038.     }
  2039. }