src/Utils/AddToCart.php line 265

Open in your IDE?
  1. <?php
  2. namespace App\Utils;
  3. use App\Entity\Gos\Cart;
  4. use App\Entity\Gos\Country;
  5. use App\Entity\Gos\Coupon;
  6. use App\Entity\Gos\PaymentMethod;
  7. use App\Entity\Gos\PortalSettings;
  8. use App\Entity\Gos\ProductAssociation;
  9. use App\Entity\Gos\ProductCart;
  10. use App\Entity\Gos\ProductPack;
  11. use App\Entity\Gos\ProductPackItem;
  12. use App\Entity\Gos\ProductVariant;
  13. use App\Entity\Gos\Uniqskills\Course;
  14. use App\Entity\Gos\User;
  15. use App\Enum\UpsellingTypes;
  16. use App\Utils\Cart\CartPriceCalculator;
  17. use App\Utils\FacebookPixel\Api\FacebookPixelService;
  18. use App\Utils\Region\CountryService;
  19. use Doctrine\ORM\EntityManagerInterface;
  20. use Symfony\Component\HttpFoundation\Cookie;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpFoundation\RequestStack;
  23. use Symfony\Component\HttpFoundation\Response;
  24. use Symfony\Component\Security\Core\Security;
  25. use Symfony\Contracts\Translation\TranslatorInterface;
  26. class AddToCart
  27. {
  28.     private ?Request $request;
  29.     private EntityManagerInterface $em;
  30.     private CartServices $cartServices;
  31.     private TranslatorInterface $translator;
  32.     private CountryService $countryService;
  33.     private FacebookPixelService $facebookPixelService;
  34.     private PortalSettingsService $portalSettingsService;
  35.     private CouponClass $couponClass;
  36.     private $paymentMethod;
  37.     private $portalSettings;
  38.     private $cart null;
  39.     private $user;
  40.     private $productsForGA = [];
  41.     private $status  false;
  42.     private $message false;
  43.     private CartPriceCalculator $cartPriceCalculator;
  44.     public function __construct(
  45.         RequestStack $requestStack,
  46.         EntityManagerInterface $entityManager,
  47.         Security $security,
  48.         CartServices $cartServices,
  49.         TranslatorInterface $translator,
  50.         CountryService $countryService,
  51.         FacebookPixelService $facebookPixelService,
  52.         PortalSettingsService $portalSettingsService,
  53.         CouponClass $couponClass,
  54.         CartPriceCalculator $cartPriceCalculator
  55.     ) {
  56.         $this->request               $requestStack->getCurrentRequest();
  57.         $this->em                    $entityManager;
  58.         $this->user                  $security->getUser();
  59.         $this->cartServices          $cartServices;
  60.         $this->translator            $translator;
  61.         $this->countryService        $countryService;
  62.         $this->facebookPixelService  $facebookPixelService;
  63.         $this->portalSettingsService $portalSettingsService;
  64.         $this->couponClass           $couponClass;
  65.         $this->cartPriceCalculator   $cartPriceCalculator;
  66.         $this->findPortalSettings();
  67.         $this->findCart();
  68.         $this->findPaymentMethod();
  69.     }
  70.     public function addVoucherToCart($voucherCode)
  71.     {
  72.         $voucherCoupon $this->em->getRepository(Coupon::class)->findVoucherCode($voucherCode);
  73.         $voucherVariant $voucherCoupon->getGift()->getOrderProductVariant()->getProductVariant()->getProductVariantNoComplete();
  74.         if ($this->request === null)
  75.         {
  76.             return false;
  77.         }
  78.         $this->request->request->set('productVariantNoComplete'$voucherVariant);
  79.         $this->request->request->set('coupon'$voucherCoupon->getCode());
  80.         $this->request->request->set('returnCart'true);
  81.         return $this->addToCart();
  82.     }
  83.     public function addToCart($user nullstring $productVariantNo null)
  84.     {
  85.         $this->user $user;
  86.         $repoPC     $this->em->getRepository(ProductCart::class);
  87.         if ($this->request->get('clearCart'))
  88.         {
  89.             /** @var ProductCart $productCart */
  90.             foreach ($this->cart->getProductCart() as $productCart)
  91.             {
  92.                 $this->cartServices->removeProductFromCart($user$productCart->getId());
  93.             }
  94.             $this->em->flush();
  95.             $this->em->refresh($this->cart);
  96.         }
  97.         if (
  98.             $this->request->get('portalHash')
  99.             || (
  100.                 $this->cart->getPortalSettings() === null
  101.                 && $this->request->getSession()->has('portalSettingsHash')
  102.             )
  103.         )
  104.         {
  105.             $this->findPortalSettings();
  106.             if ($this->portalSettings)
  107.             {
  108.                 $this->cart->setPortalSettings($this->portalSettings);
  109.             }
  110.             $this->em->flush();
  111.             $this->em->refresh($this->cart);
  112.         }
  113.         $newProductVariant $this->findProductVariantToAdd($productVariantNo);
  114.         $newProductPack    $this->findProductPackToAdd();
  115.         if (empty($newProductVariant) && empty($newProductPack))
  116.         {
  117.             $this->addCoupon(); // Add coupon to existing products in cart anyway
  118.             return ['error' => 'Product not found'];
  119.         }
  120.         if (isset($newProductVariant['error']))
  121.         {
  122.             return $newProductVariant;
  123.         }
  124.         $this->addToCartProductPack($newProductPack);
  125.         $this->addToCartProductVariant($newProductVariant);
  126.         $this->addCoupon();
  127.         if ($this->request->request->get('returnCart'false))
  128.         {
  129.             return array(
  130.                 'status'   => $this->status,
  131.                 'redirect' => 1
  132.             );
  133.         }
  134.         $price $this->cartPriceCalculator->getCartPrice($this->cart); // return price with postage cost
  135.         foreach ($this->productsForGA as $key => $product)
  136.         {
  137.             $this->productsForGA[$key]['price'] = $price[$product['ppiId'] ?? $product['pvId']]->totalPriceAfterCouponGross;
  138.         }
  139.         return [
  140.             'quantity'       => $repoPC->sumProductCart($this->cart->getHash()),
  141.             'cartTotalPrice' => $price['totalPriceAfterCouponGross'],
  142.             'message'        => $this->message,
  143.             'status'         => $this->status,
  144.             'products'       => $this->productsForGA
  145.         ];
  146.     }
  147.     public function getHash(): string
  148.     {
  149.         return $this->cart->getHash();
  150.     }
  151.     private function findProductVariantToAdd(?string $productVariantNo)
  152.     {
  153.         $newProductVariant        = array();
  154.         $productVariantNoComplete $productVariantNo ?: $this->request->get('productVariantNoComplete');
  155.         if (!empty($productVariantNoComplete))
  156.         {
  157.             $arrayProductVariantNo  explode(','$productVariantNoComplete);
  158.             $newProductVariant      $this->em->getRepository(ProductVariant::class)
  159.                 ->findProductVariantToAdd($arrayProductVariantNo);
  160.             if (!empty($newProductVariant)
  161.                 && ($this->request->request->get('source') == 'uniqskills'
  162.                 || $this->request->query->get('source') == 'uniqskills'))
  163.             {
  164.                 foreach ($newProductVariant as $npv)
  165.                 {
  166.                     $this->facebookPixelService
  167.                         ->setEvent('AddToCart'$npv->getId())
  168.                         ->request();
  169.                     /** @var $npv ProductVariant */
  170.                     $userCountry $this->countryService->getCountry($this->request$this->user);
  171.                     $exploded explode('/'parse_url($this->request->headers->get('referer'), PHP_URL_PATH));
  172.                     $isInCart end($exploded) === 'cart';
  173.                     if (((empty($npv->getCountry()) && $userCountry && $userCountry->getAlpha2() != 'PL')
  174.                         || $userCountry != $npv->getCountry()) && !$isInCart)
  175.                     {
  176.                         return [
  177.                             'status'    => false,
  178.                             'error'     => 'wrongCountry',
  179.                             'message'   => $this->translator->trans(
  180.                                 'errors.order.wrongCountry',
  181.                                 [],
  182.                                 'messages',
  183.                                 $this->request->getSession()->get('userLocale''pl')
  184.                             )
  185.                         ];
  186.                     }
  187.                 }
  188.             }
  189.             $portal $this->portalSettingsService->getPortalSettings();
  190.             if ($portal && $portal->getUseFbPixelInIframe() === true)
  191.             {
  192.                 foreach ($newProductVariant as $npv)
  193.                 {
  194.                     $this->facebookPixelService
  195.                         ->setEvent('AddToCart'$npv->getId())
  196.                         ->request();
  197.                 }
  198.             }
  199.         }
  200.         return $newProductVariant;
  201.     }
  202.     private function findProductPackToAdd()
  203.     {
  204.         $newProductPack = array();
  205.         $productPackId  $this->request->get('productPackId');
  206.         if (!empty($productPackId))
  207.         {
  208.             $arrayProductPackId explode(','$productPackId);
  209.             $newProductPack     $this->em->getRepository(ProductPack::class)
  210.                 ->findProductPackToAdd($arrayProductPackId);
  211.         }
  212.         return $newProductPack;
  213.     }
  214.     private function findCart()
  215.     {
  216.         $cartHash $this->getCartHash();
  217.         if (!empty($cartHash))
  218.         {
  219.             $this->cart $this->em->getRepository(Cart::class)->findOneByHash($cartHash);
  220.         }
  221.         if (empty($this->cart))
  222.         {
  223.             $this->cart $this->cartServices->createCart($this->user instanceof User $this->user false);
  224.         }
  225.         $this->request->getSession()->set('cartHash'$this->cart->getHash());
  226.     }
  227.     private function findPortalSettings()
  228.     {
  229.         $hash                 $this->request->getSession()->get('portalSettingsHash');
  230.         $this->portalSettings $this->em->getRepository(PortalSettings::class)->findOneByHash($hash);
  231.     }
  232.     private function findPaymentMethod()
  233.     {
  234.         $this->paymentMethod $this->em->getRepository(PaymentMethod::class)->findOneBySlug('invoice');
  235.     }
  236.     private function getCartHash()
  237.     {
  238.         if ($this->user instanceof User && $this->user->getCart())
  239.         {
  240.             return $this->user->getCart()->getHash();
  241.         }
  242.         if ($this->request->getSession()->has('cartHash'))
  243.         {
  244.             return $this->request->getSession()->get('cartHash');
  245.         }
  246.         return $this->request->cookies->get('cartHash'$this->request->get('cartHash'));
  247.     }
  248.     /**
  249.      * Add coupon
  250.      */
  251.     public function addCoupon($couponCode null)
  252.     {
  253.         if (!$couponCode)
  254.         {
  255.             $couponCode $this->request->request->get('coupon'$this->request->query->get('coupon'false));
  256.         }
  257.         if ($couponCode)
  258.         {
  259.             $couponCodes explode('|'$couponCode);
  260.             foreach ($couponCodes as $code)
  261.             {
  262.                 $coupon      $this->couponClass->add($this->cart$code);
  263.                 $this->em->refresh($this->cart);
  264.                 if (isset($coupon['message']))
  265.                 {
  266.                     $this->request->getSession()->getFlashBag()->add('warningCart'$coupon['message']);
  267.                 }
  268.             }
  269.         }
  270.     }
  271.     private function createProductCart(ProductVariant $productVariant null$productPack null$additionalUpselling false)
  272.     {
  273.         $productCart = (new ProductCart())
  274.             ->setPaymentMethod($this->paymentMethod)
  275.             ->setQuantity(1)
  276.             ->setCart($this->cart);
  277.         if ($additionalUpselling === true$productCart->setUpsellingType(UpsellingTypes::FORCED);
  278.         if ($productVariant)
  279.         {
  280.             $productCart->setProductVariant($productVariant);
  281.             if ($productPack)
  282.             {
  283.                 $productCart->setCycleProductPack($productPack);
  284.             }
  285.         }
  286.         elseif ($productPack)
  287.         {
  288.             $productCart->setProductPack($productPack);
  289.         }
  290.         $countClients $this->request->request->get('countClients'false);
  291.         if ($countClients && $countClients 1)
  292.         {
  293.             $productCart->setQuantity($countClients);
  294.         }
  295.         $this->couponClass->assignCouponsToProductCart($productCart);
  296.         return $productCart;
  297.     }
  298.     public function addToCartProductVariant($newProductVariant$additionalUpselling false): void
  299.     {
  300.         $repoPC $this->em->getRepository(ProductCart::class);
  301.         $isGift $this->request->get('gift'false);
  302.         foreach ($newProductVariant as $newPV)
  303.         {
  304.             /** @var ProductCart $productCart */
  305.             $productCart $repoPC->findCartOnProductVariant($this->cart->getHash(), $newPV->getId());
  306.             if ($productCart and $additionalUpselling === true) continue;
  307.             /** @var ProductVariant $newPV */
  308.             if ($newPV->isSaleDisabled())
  309.             {
  310.                 $this->message $this->translator->trans(
  311.                     'errors.order.saleDisabled',
  312.                     [],
  313.                     'messages',
  314.                     $this->request->getSession()->get('userLocale''pl')
  315.                 );
  316.                 if ($productCart)
  317.                 {
  318.                     $this->cart->removeProductCart($productCart);
  319.                     $this->em->persist($productCart);
  320.                     $this->em->flush();
  321.                 }
  322.                 return;
  323.             }
  324.             /** @var ProductVariant $newPV */
  325.             if ($newPV->isActive())
  326.             {
  327.                 if ($productCart)
  328.                 {
  329.                     $quantity $productCart->getQuantity();
  330.                     if ($productCart->hasUniqskillsMultiUserCourse()
  331.                         && $quantity === $productCart->getProductVariant()->getMaxUsers())
  332.                     {
  333.                         $this->status true;
  334.                         return;
  335.                     }
  336.                     else
  337.                         $productCart->setQuantity($newPV->getBuyMaxOne() ? : ++$quantity);
  338.                 }
  339.                 else
  340.                 {
  341.                     if ($this->checkIfProductIsCorrectCountry($newPV))
  342.                     {
  343.                         $this->setCountryToCart($newPV);
  344.                         $productCart $this->createProductCart($newPVnull$additionalUpselling);
  345.                     }
  346.                     else
  347.                     {
  348.                         $this->message $this->translator->trans(
  349.                             'errors.order.wrongCountry',
  350.                             [],
  351.                             'messages',
  352.                             $this->request->getSession()->get('userLocale''pl')
  353.                         );
  354.                         if ($productCart)
  355.                         {
  356.                             $this->cart->removeProductCart($productCart);
  357.                             $this->em->persist($productCart);
  358.                             $this->em->flush();
  359.                         }
  360.                         return;
  361.                     }
  362.                 }
  363.                 if ($isGift)
  364.                 {
  365.                     $productCart->setIsGift(true);
  366.                 }
  367.                 if ($this->request->request->get('productAssociationId'))
  368.                 {
  369.                     $productAssociationId $this->request->request->get('productAssociationId');
  370.                     $productAssociation $this->em->getRepository(ProductAssociation::class)->find($productAssociationId);
  371.                     if ($productAssociation)
  372.                     {
  373.                         $productCart->setProductAssociation($productAssociation);
  374.                     }
  375.                 }
  376.                 if ($this->request->get('source') == 'uniqskills')
  377.                 {
  378.                     $productCart->setLifetimeLanding($this->request->get('lifetimeLanding'false));
  379.                     $courseSlug $this->request->get('courseSlug');
  380.                     $course $this->em->getRepository(Course::class)->findOneBySlug($courseSlug);
  381.                     if (!is_null($course)) $productCart->setCourse($course);
  382.                 }
  383.                 $upsellingType = (int)$this->request->get('upsellingType');
  384.                 if ($upsellingType && UpsellingTypes::isValidValue($upsellingType))
  385.                 {
  386.                     $productCart->setUpsellingType($upsellingType);
  387.                 }
  388.                 if (
  389.                     $this->request->get('parentProductCart')
  390.                     &&
  391.                     $parentProductCart $repoPC->find($this->request->get('parentProductCart'))
  392.                 )
  393.                 {
  394.                     $productCart->setParent($parentProductCart);
  395.                     $productCart->setQuantity($parentProductCart->getQuantity());
  396.                 }
  397.                 $this->em->persist($this->cart);
  398.                 $this->em->persist($productCart);
  399.                 $this->em->flush();
  400.                 $this->em->refresh($this->cart);
  401.                 $productVariant $productCart->getProductVariant();
  402.                 $this->productsForGA[] = array(
  403.                     'pvId'                      => $productVariant->getId(),
  404.                     'productVariantNoComplete'  => $productVariant->getProductVariantNoComplete(),
  405.                     'tradeName'                 => $productVariant->getTradeName(),
  406.                     'price'                     => 0,
  407.                     'brand'                     => $productVariant->getMasterProduct()->getProductGroups() ? $productVariant->getMasterProduct()->getProductGroups()->getName() : '',
  408.                     'category'                  => $productVariant->getMasterProduct()->getProductType() ? $productVariant->getMasterProduct()->getProductType()->getName() : '',
  409.                     'quantity'                  => $productCart->getQuantity(),
  410.                     'coupon'                    => $productCart->getCoupon() ? $productCart->getCoupon()->getCode() : null
  411.                 );
  412.                 $this->status  true;
  413.             }
  414.             else
  415.             {
  416.                 $this->message $this->translator->trans(
  417.                     'errors.order.notAvailable',
  418.                     [],
  419.                     'messages',
  420.                     $this->request->getSession()->get('userLocale''pl')
  421.                 );
  422.                 if ($productCart)
  423.                 {
  424.                     $this->cart->removeProductCart($productCart);
  425.                     $this->em->persist($productCart);
  426.                     $this->em->flush();
  427.                 }
  428.             }
  429.         }
  430.     }
  431.     public function setButtonParameterCookie(Response $response): void
  432.     {
  433.         if ($this->request && $this->request->request->get('bp'))
  434.         {
  435.             $bp $this->request->cookies->get('bp', array());
  436.             if (!empty($bp))
  437.             {
  438.                 $bp json_decode($bp);
  439.             }
  440.             $bp[] = $this->request->request->get('bp');
  441.             $response->headers->setCookie(new Cookie("bp"json_encode(array_unique($bp)), time() + (3600 24 30)));
  442.         }
  443.     }
  444.     public function addToCartProductPack($newProductPack): void
  445.     {
  446.         $repoPC   $this->em->getRepository(ProductCart::class);
  447.         foreach ($newProductPack as $newPP)
  448.         {
  449.             /** @var ProductPack $newPP */
  450.             /** @var ProductCart $productCart */
  451.             $productCart $repoPC->findCartOnProductPack($this->cart->getHash(), $newPP->getId());
  452.             if ($newPP->isActive())
  453.             {
  454.                 if ($productCart)
  455.                 {
  456.                     $quantity $productCart->getQuantity();
  457.                     $productCart->setQuantity($newPP->getBuyMaxOne() ? : ++$quantity);
  458.                 }
  459.                 else
  460.                 {
  461.                     if ($this->checkIfPackIsCorrectCountry($newPP))
  462.                     {
  463.                         $this->setCountryToCartFromPack($newPP);
  464.                         if ($this->request->request->get('isCycle'))
  465.                         {
  466.                             /** @var ProductPackItem $firstPackItem */
  467.                             $firstPackItem $newPP->getProductPackItem()->first();
  468.                             $firstProductVariant $firstPackItem->getProductVariant();
  469.                             $productCart $repoPC->findCartOnProductVariant($this->cart->getHash(), $firstProductVariant->getId());
  470.                             if (!$productCart)
  471.                             {
  472.                                 $productCart $this->createProductCart($firstProductVariant$newPP);
  473.                             }
  474.                         }
  475.                         else
  476.                         {
  477.                             $productCart $this->createProductCart(null$newPP);
  478.                         }
  479.                     }
  480.                     else
  481.                     {
  482.                         $this->message $this->translator->trans(
  483.                             'errors.order.wrongCountry',
  484.                             [],
  485.                             'messages',
  486.                             $this->request->getSession()->get('userLocale''pl')
  487.                         );
  488.                         return;
  489.                     }
  490.                 }
  491.                 $this->em->persist($productCart);
  492.                 $this->em->flush();
  493.                 $this->em->refresh($this->cart);
  494.                 $this->facebookPixelService
  495.                     ->setEvent('AddToCart'$newPP->getId(), true)
  496.                     ->request();
  497.                 foreach ($newPP->getProductPackItem() as $item)
  498.                 {
  499.                     $pv $item->getProductVariant();
  500.                     $this->productsForGA[] = [
  501.                         'ppiId'                     => $item->getId(),
  502.                         'ppId'                      => $newPP->getId(),
  503.                         'pvId'                      => $pv->getId(),
  504.                         'productVariantNoComplete'  => $pv->getProductVariantNoComplete(),
  505.                         'tradeName'                 => $pv->getTradeName(),
  506.                         'price'                     => 0,
  507.                         'brand'                     => $pv->getMasterProduct()->getProductGroups() ? $pv->getMasterProduct()->getProductGroups()->getName() : '',
  508.                         'category'                  => $pv->getMasterProduct()->getProductType() ? $pv->getMasterProduct()->getProductType()->getName() : '',
  509.                         'quantity'                  => $productCart->getQuantity() ?? 1,
  510.                         'coupon'                    => $productCart->getCoupon() ? $productCart->getCoupon()->getCode() : null
  511.                     ];
  512.                 }
  513.                 $this->status  true;
  514.             }
  515.             else
  516.             {
  517.                 $this->message $this->translator->trans(
  518.                     'errors.order.notAvailable',
  519.                     [],
  520.                     'messages',
  521.                     $this->request->getSession()->get('userLocale''pl')
  522.                 );
  523.                 if ($productCart)
  524.                 {
  525.                     $this->cart->removeProductCart($productCart);
  526.                     $this->em->persist($productCart);
  527.                     $this->em->flush();
  528.                 }
  529.             }
  530.         }
  531.     }
  532.     private function checkIfPackIsCorrectCountry(ProductPack $pp): bool
  533.     {
  534.         /** @var ProductPackItem $productPackItem */
  535.         $productPackItem $pp->getProductPackItem()->first();
  536.         return $this->checkIfProductIsCorrectCountry($productPackItem->getProductVariant());
  537.     }
  538.     private function checkIfProductIsCorrectCountry(ProductVariant $pv null)
  539.     {
  540.         if ($this->cart->getProductCart()->count() < && $this->cart->getCountry())
  541.         {
  542.             $this->cart->setCountry(null);
  543.         }
  544.         if (empty($this->cart->getCountry()) || empty($pv))
  545.         {
  546.             return true;
  547.         }
  548.         if ($pv->getCountry())
  549.         {
  550.             if ($pv->getCountry() === $this->cart->getCountry())
  551.                 return true;
  552.             else
  553.                 return false;
  554.         }
  555.         else
  556.         {
  557.             if ($this->cart->getCountry()->getAlpha2() === 'PL')
  558.                 return true;
  559.             else
  560.                 return false;
  561.         }
  562.     }
  563.     private function setCountryToCartFromPack(ProductPack $pp): void
  564.     {
  565.         /** @var ProductPackItem $productPackItem */
  566.         $productPackItem $pp->getProductPackItem()->first();
  567.         $this->setCountryToCart($productPackItem->getProductVariant());
  568.     }
  569.     private function setCountryToCart(ProductVariant $pv null)
  570.     {
  571.         if (empty($this->cart->getCountry()))
  572.         {
  573.             if ($pv && $pv->getCountry())
  574.             {
  575.                 $this->cart->setCountry($pv->getCountry());
  576.             }
  577.             else
  578.             {
  579.                 $poland $this->em->getRepository(Country::class)->findOneByAlpha2('PL');
  580.                 $this->cart->setCountry($poland);
  581.             }
  582.         }
  583.     }
  584. }