src/Service/Cart/CartService.php line 113

Open in your IDE?
  1. <?php
  2. /**
  3.  * @author <akartis-dev>
  4.  */
  5. namespace App\Service\Cart;
  6. use App\Doctrine\Type\Order\OrderPrestationStatusType;
  7. use App\Doctrine\Type\Order\OrderStatusType;
  8. use App\Doctrine\Type\PromotionalCode\PromotionalCodeType;
  9. use App\Entity\Orders\Orders;
  10. use App\Entity\Orders\OrdersPrestations;
  11. use App\Entity\Orders\OrdersProducts;
  12. use App\Entity\Pharmacies\PharmaciesProducts;
  13. use App\Entity\PharmacyNotification;
  14. use App\Entity\Products\Attribut\ProductsAttributsTerms;
  15. use App\Entity\Products\Products;
  16. use App\Entity\Products\ProductsPrestations;
  17. use App\Entity\PromotionalCode\PromotionalCode;
  18. use App\EntityPharmonline\PharmaciesServices;
  19. use App\EntityPharmonline\Users;
  20. use App\Exception\PromoCodeException;
  21. use App\Form\Orders\OrderBillingModel;
  22. use App\Kernel;
  23. use App\ObjectManager\EntityObjectManager;
  24. use App\Repository\Gift\OrderGiftRepository;
  25. use App\Repository\Pharmacies\PharmaciesRepository;
  26. use App\Repository\Products\Attribut\ProductsAttributsTermsRepository;
  27. use App\Repository\Products\ProductsRepository;
  28. use App\Service\Constant\NotificationConstant;
  29. use App\Service\Constant\OrderConstant;
  30. use App\Service\Constant\PaymentConstant;
  31. use App\Service\Constant\SessionConstant;
  32. use App\Service\Constant\ShippingMethodConstant;
  33. use App\Service\Gift\GiftService;
  34. use App\Service\Mailer\UserMailer;
  35. use App\Service\PromotionalCode\PromotionalCodeService;
  36. use JetBrains\PhpStorm\ArrayShape;
  37. use Symfony\Component\HttpFoundation\RedirectResponse;
  38. use Symfony\Component\HttpFoundation\RequestStack;
  39. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  40. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  41. use Symfony\Component\Security\Core\Security;
  42. use Symfony\Component\Serializer\SerializerInterface;
  43. use Symfony\Contracts\Translation\TranslatorInterface;
  44. class CartService
  45. {
  46.     public function __construct(
  47.         private RequestStack                     $requestStack,
  48.         private ProductsRepository               $productsRepository,
  49.         private PharmaciesRepository             $pharmaciesRepository,
  50.         private ProductsAttributsTermsRepository $productsAttributsTermsRepository,
  51.         private SerializerInterface              $serializer,
  52.         private Kernel                           $kernel,
  53.         private EntityObjectManager              $em,
  54.         private UrlGeneratorInterface            $urlGenerator,
  55.         private Security                         $security,
  56.         private TranslatorInterface              $translator,
  57.         private OrderGiftRepository              $orderGiftRepository,
  58.         private UserMailer                       $userMailer
  59.     )
  60.     {
  61.     }
  62.     /**
  63.      * Add or increment product in cart
  64.      *
  65.      * @param int $productId
  66.      * @param int|null $pharmacyId
  67.      * @param int|null $attributId
  68.      * @param int|null $quantity
  69.      * @return bool
  70.      */
  71.     public function addInCart(int $productId, ?int $pharmacyId, ?int $attributId, ?int $quantity): bool
  72.     {
  73.         $currentCart $this->getCartFromSession();
  74.         $product $this->productsRepository->find($productId);
  75.         if (!$product) {
  76.             return false;
  77.         }
  78.         $containAttribut $product->getProductsAttributsTerms()
  79.             ->filter(
  80.                 function (ProductsAttributsTerms $productsAttributsTerms) use ($attributId) {
  81.                     return $productsAttributsTerms->getId() === $attributId;
  82.                 }
  83.             );
  84.         $this->updateProductInCartSession(
  85.             product$product,
  86.             pharmaciesProductsnull,
  87.             attributsTerms$containAttribut->first(),
  88.             quantity$quantity
  89.         );
  90.         return true;
  91.     }
  92.     /**
  93.      * Get cart from session
  94.      *
  95.      */
  96.     private function getCartFromSession(): array
  97.     {
  98.         $session $this->requestStack->getSession();
  99.         if (!$session->has(SessionConstant::CART)) {
  100.             $session->set(SessionConstant::CART, []);
  101.             return [];
  102.         }
  103.         return $session->get(SessionConstant::CART);
  104.     }
  105.     /**
  106.      * Get coupon code from session
  107.      *
  108.      */
  109.     private function getCouponFromSession(): array
  110.     {
  111.         $session $this->requestStack->getSession();
  112.         if (!$session->has(SessionConstant::COUPONS_CODE)) {
  113.             $session->set(SessionConstant::COUPONS_CODE, []);
  114.             return [];
  115.         }
  116.         return $session->get(SessionConstant::COUPONS_CODE);
  117.     }
  118.     /**
  119.      * Create new product in session cart
  120.      * Update quantity and price total if already present
  121.      *
  122.      * @param Products $product
  123.      * @param int|null $pharmacyId
  124.      * @param int|null $attributId
  125.      */
  126.     #[ArrayShape(['product' => "int|null"'pharmacy' => "int|null"'attribut' => "int|null"'price' => "int""quantity" => "int""total" => "int"])]
  127.     private function updateProductInCartSession(
  128.         Products                    $product,
  129.         ?PharmaciesProducts         $pharmaciesProducts,
  130.         ProductsAttributsTerms|bool $attributsTerms,
  131.         int                         $quantity
  132.     ): void
  133.     {
  134.         $cart $this->getCartFromSession();
  135.         $price $product->inPromotion() ? $product->getPriceWithPromotion() : $product->getPrice();
  136.         $session $this->requestStack->getSession();
  137.         $attributId $attributsTerms $attributsTerms->getId() : 0;
  138.         if (
  139.             $attributsTerms &&
  140.             $attributsTerms->getPrice() &&
  141.             $attributsTerms->getPrice() > 0
  142.         ) {
  143.             $pourcentPromotion number_format(100 - ($product->getPriceWithPromotion() * 100 $product->getPrice()), 0);
  144.             $price $attributsTerms->getPrice() * (- ((int)$pourcentPromotion 100));
  145.         }
  146.         $alreadyPresent false;
  147.         foreach ($cart as $key => $cartProduct) {
  148.             if ($cartProduct['product'] === $product->getId() && $cartProduct['attribut'] === $attributId) {
  149.                 $quantity $cartProduct['quantity'] + $quantity;
  150.                 $cartProduct['quantity'] = $quantity;
  151.                 $cartProduct['total'] = $cartProduct['price'] * $quantity;
  152.                 $alreadyPresent true;
  153.                 $cart[$key] = $cartProduct;
  154.             }
  155.         }
  156.         if (!$alreadyPresent) {
  157.             $cart[] = [
  158.                 'product' => $product->getId(),
  159.                 'pharmacy' => $pharmaciesProducts $pharmaciesProducts->getPharmacy()->getId() : 0,
  160.                 'attribut' => $attributId,
  161.                 'price' => $price,
  162.                 "quantity" => $quantity ?? 1,
  163.                 "total" => $price $quantity,
  164.                 "promotion" => 0,
  165.                 'prestation' => null
  166.             ];
  167.         }
  168.         $session->set(SessionConstant::CART$cart);
  169.         $session->save();
  170.     }
  171.     /**
  172.      * Add a new coupon code in session
  173.      *
  174.      * @param PromotionalCode $promoCode
  175.      * @return bool
  176.      */
  177.     public function addCouponCode(PromotionalCode $promoCode): bool
  178.     {
  179.         $session $this->requestStack->getSession();
  180.         $couponCode $this->getCouponCode();
  181.         $data = [
  182.             'ref' => $promoCode->getReference(),
  183.             'type' => $promoCode->getType(),
  184.             'discount' => $promoCode->getPromoDiscount(),
  185.             'combine' => $promoCode->getCombineOtherCoupons()
  186.         ];
  187.         $alreadyExist false;
  188.         foreach ($couponCode as $coupon) {
  189.             if ($coupon['ref'] === $promoCode->getReference()) {
  190.                 $alreadyExist true;
  191.                 break;
  192.             }
  193.         }
  194.         if (!$alreadyExist) {
  195.             $couponCode[] = $data;
  196.             $session->set(SessionConstant::COUPONS_CODE$couponCode);
  197.             $session->save();
  198.         }
  199.         return $alreadyExist;
  200.     }
  201.     /**
  202.      * Remove product in session cart
  203.      *
  204.      * @param int $productId
  205.      * @return array
  206.      */
  207.     public function subProductInSessionCart(int $productId, ?int $attributbool $all false): array|bool
  208.     {
  209.         $currentCart $this->getCartFromSession();
  210.         $product $this->productsRepository->find($productId);
  211.         if (!$product) {
  212.             return false;
  213.         }
  214.         foreach ($currentCart as $key => $cartItem) {
  215.             if ((int)$cartItem['product'] === $product->getId()) {
  216.                 $quantity $all $cartItem['quantity'] - 1;
  217.                 if ($attribut === 0) {
  218.                     $currentCart[$key]['quantity'] = $quantity;
  219.                     $currentCart[$key]['total'] = $cartItem['price'] * $quantity;
  220.                 } else if ($attribut === $cartItem['attribut']) {
  221.                     $currentCart[$key]['quantity'] = $quantity;
  222.                     $currentCart[$key]['total'] = $cartItem['price'] * $quantity;
  223.                 }
  224.             }
  225.         }
  226.         $prestations $this->getCartPrestation();
  227.         foreach ($currentCart as $key => $cartItem) {
  228.             if ($cartItem['quantity'] <= 0) {
  229.                 /** Remove attached prestation */
  230.                 foreach ($prestations as $prestationKey => $prestation) {
  231.                     if ($prestation['productPrestation']->getProduct()->getId() === $cartItem['product']) {
  232.                         unset($prestations[$prestationKey]);
  233.                         break;
  234.                     }
  235.                 }
  236.                 unset($currentCart[$key]);
  237.             }
  238.         }
  239.         $reassignedPrestation array_map(static function ($item) {
  240.             return [
  241.                 "prestations" => (int)$item['productPrestation']->getPrestationId(),
  242.                 "productId" => (int)$item['productPrestation']->getProduct()->getId(),
  243.                 "pharmacyServiceId" => (int)$item['pharmacyPrestation']->getId()
  244.             ];
  245.         }, $prestations);
  246.         $this->handleAddPrestations($reassignedPrestation);
  247.         $this->reassignAllCartInSession($currentCart);
  248.         return $this->reverifyCouponCartUpdated();
  249.     }
  250.     /**
  251.      * Get cart with related entity
  252.      *
  253.      * @return array
  254.      * @throws \JsonException
  255.      */
  256.     public
  257.     function getHydratedCart(): array
  258.     {
  259.         $currentCart $this->getCartFromSession();
  260.         $results = [];
  261.         foreach ($currentCart as $cartItem) {
  262.             $product $this->serializer->serialize(
  263.                 $this->productsRepository->find($cartItem['product']), 'json', ['groups' => 'product']
  264.             );
  265.             $pharmacy $this->serializer->serialize(
  266.                 $this->pharmaciesRepository->find($cartItem['pharmacy']), 'json', ['groups' => 'pharmacy']
  267.             );
  268.             $attribut $this->serializer->serialize(
  269.                 $this->productsAttributsTermsRepository->find($cartItem['attribut']), 'json', ['groups' => 'productAttributTerm']
  270.             );
  271.             $item = [
  272.                 'product' => json_decode($producttrue512JSON_THROW_ON_ERROR),
  273.                 'pharmacy' => json_decode($pharmacytrue512JSON_THROW_ON_ERROR),
  274.                 'attribut' => json_decode($attributtrue512JSON_THROW_ON_ERROR),
  275.                 'price' => $cartItem['price'],
  276.                 "quantity" => $cartItem['quantity'],
  277.                 "total" => $cartItem['total'],
  278.                 "promotion" => $cartItem['promotion'],
  279.                 "prestation" => null
  280.             ];
  281.             if (is_array($cartItem['prestation'] ?? null)) {
  282.                 $data = [
  283.                     'productPrestation' => $cartItem['prestation']['productPrestation'],
  284.                     "pharmacyPrestation" => $cartItem['prestation']['pharmacyPrestation'],
  285.                     "price" => $cartItem['prestation']['price'],
  286.                 ];
  287.                 $item['prestation'] = $data;
  288.             }
  289.             $results[] = $item;
  290.         }
  291.         return $results;
  292.     }
  293.     /**
  294.      * Get cart with related entity not serialized
  295.      *
  296.      * @return array<string, array{
  297.      *     'product' => Products::class,
  298.      *     'pharmacy' => Pharmacies::class | null,
  299.      *     'attribut' => ProductsAttributsTerms::class | null,
  300.      *     'price' => "int",
  301.      *     "quantity" => "int",
  302.      *     "total" => "int"
  303.      * }>
  304.      * @throws \JsonException
  305.      */
  306.     public function getHydratedCartNoSerializable(): array
  307.     {
  308.         $productPrestationRepository $this->em->getEm()->getRepository(ProductsPrestations::class);
  309.         $pharmacyPrestationRepository $this->em->getPharmonlineEm()->getRepository(PharmaciesServices::class);
  310.         $currentCart $this->getCartFromSession();
  311.         $results = [];
  312.         foreach ($currentCart as $cartItem) {
  313.             $item = [
  314.                 'product' => $this->productsRepository->findOneBy(['id' => $cartItem['product']]),
  315.                 'pharmacy' => $this->pharmaciesRepository->find($cartItem['pharmacy']),
  316.                 'attribut' => $this->productsAttributsTermsRepository->find($cartItem['attribut']),
  317.                 'price' => $cartItem['price'],
  318.                 "quantity" => $cartItem['quantity'],
  319.                 "total" => $cartItem['total'],
  320.                 "promotion" => $cartItem['promotion'],
  321.                 "prestation" => null
  322.             ];
  323.             if (is_array($cartItem['prestation'] ?? null)) {
  324.                 $data = [
  325.                     'productPrestation' => $productPrestationRepository->find($cartItem['prestation']['productPrestation']),
  326.                     "pharmacyPrestation" => $pharmacyPrestationRepository->find($cartItem['prestation']['pharmacyPrestation']),
  327.                     "price" => $cartItem['prestation']['price'],
  328.                 ];
  329.                 $item['prestation'] = $data;
  330.             }
  331.             $results[] = $item;
  332.         }
  333.         return $results;
  334.     }
  335.     /**
  336.      * Get all coupon code for this order
  337.      *
  338.      * @return array[
  339.      * 'ref' => string,
  340.      * 'type' => string,
  341.      * 'discount' => int
  342.      * ]
  343.      *
  344.      */
  345.     public function getCouponCode(): array
  346.     {
  347.         return $this->getCouponFromSession();
  348.     }
  349.     /**
  350.      * Get cart total with all coupon
  351.      *
  352.      * @return string
  353.      * @throws \JsonException
  354.      */
  355.     public function getCartTotalWithCoupon(): string
  356.     {
  357.         $coupons $this->getCouponCode();
  358.         $cart $this->getHydratedCart();
  359.         $total $this->getTotalBrut();
  360.         foreach ($coupons as $coupon) {
  361.             if ($coupon['type'] === PromotionalCodeType::AMOUNT) {
  362.                 $total -= $coupon['discount'];
  363.             }
  364.             if ($coupon['type'] === PromotionalCodeType::PERCENT) {
  365.                 $total -= ($total $coupon['discount'] / 100);
  366.             }
  367.         }
  368.         return number_format($total2) . " CHF";
  369.     }
  370.     /**
  371.      * Get cart total no coupon
  372.      *
  373.      * @return string
  374.      * @throws \JsonException
  375.      */
  376.     public function getCartTotal(): string
  377.     {
  378.         $total $this->getTotalBrut();
  379.         return number_format($total2) . " CHF";
  380.     }
  381.     /**
  382.      * Get brut cart total
  383.      *
  384.      * @return float
  385.      * @throws \JsonException
  386.      */
  387.     public function getTotalBrut(): float
  388.     {
  389.         $coupons $this->getCouponCode();
  390.         $cart $this->getHydratedCart();
  391.         $total 0;
  392.         foreach ($cart as $item) {
  393.             $total += $item['total'] - $item['promotion'];
  394.             if (is_array($item["prestation"])) {
  395.                 $total += $item['prestation']['price'] ?? 0;
  396.             }
  397.         }
  398.         return $total;
  399.     }
  400.     /**
  401.      * Re-verify all coupon when cart is updated
  402.      *
  403.      * @return array
  404.      * @throws \JsonException
  405.      */
  406.     public function reverifyCouponCartUpdated(): array
  407.     {
  408.         /**
  409.          * To avoid circular reference injected
  410.          */
  411.         $promotionalCodeService $this->kernel->getContainer()->get(PromotionalCodeService::class);
  412.         $coupons $this->getCouponCode();
  413.         $this->reassignAllCouponInSession([]);
  414.         $removedCoupon = [];
  415.         foreach ($coupons as $coupon) {
  416.             try {
  417.                 $promotionalCodeService->verify($coupon['ref']);
  418.             } catch (PromoCodeException $promoCodeException) {
  419.                 $removedCoupon[] = $coupon['ref'];
  420.             }
  421.         }
  422.         $filteredCoupon array_filter($coupons, function ($coupon) use ($removedCoupon) {
  423.             return !in_array($coupon['ref'], $removedCoupontrue);
  424.         });
  425.         $this->reassignAllCouponInSession($filteredCoupon);
  426.         return $removedCoupon;
  427.     }
  428.     /**
  429.      * Reassign all coupon in session
  430.      *
  431.      * @param array $coupons
  432.      * @return void
  433.      */
  434.     public function reassignAllCouponInSession(array $coupons): void
  435.     {
  436.         $session $this->requestStack->getSession();
  437.         $session->set(SessionConstant::COUPONS_CODE$coupons);
  438.         $session->save();
  439.     }
  440.     /**
  441.      * Reassign all cart in session
  442.      *
  443.      * @param array $coupons
  444.      * @return void
  445.      */
  446.     public function reassignAllCartInSession(array $cart): void
  447.     {
  448.         $session $this->requestStack->getSession();
  449.         $session->set(SessionConstant::CART$cart);
  450.         $session->save();
  451.     }
  452.     /**
  453.      * Set pharmacy in cart
  454.      *
  455.      * @return bool
  456.      * @throws \JsonException
  457.      */
  458.     public function setPharmacyCart(int $pharmacyId): bool
  459.     {
  460.         $pharmacy $this->em->getPharmonlineEm()->getRepository(\App\EntityPharmonline\Pharmacies::class)->find($pharmacyId);
  461.         if ($pharmacy) {
  462.             $serializedPharmacy $this->serializer->serialize($pharmacy'json', ['groups' => 'pharmacy']);
  463.             $session $this->requestStack->getSession();
  464.             $session->set(SessionConstant::CART_PHARMACYjson_decode($serializedPharmacytrue512JSON_THROW_ON_ERROR));
  465.             $session->save();
  466.             return true;
  467.         }
  468.         return false;
  469.     }
  470.     /**
  471.      * Get pharmacy cart from session
  472.      * @return mixed|null
  473.      */
  474.     public function getPharmacyCart(): null|array
  475.     {
  476.         $session $this->requestStack->getSession();
  477.         if (!$session->has(SessionConstant::CART_PHARMACY)) {
  478.             return null;
  479.         }
  480.         return $session->get(SessionConstant::CART_PHARMACY);
  481.     }
  482.     /**
  483.      * Get pharmacy cart entity
  484.      *
  485.      * @return \App\EntityPharmonline\Pharmacies|null
  486.      */
  487.     public function getPharmacyHydrated(): \App\EntityPharmonline\Pharmacies|null
  488.     {
  489.         $pharmacy $this->getPharmacyCart();
  490.         if (!$pharmacy) {
  491.             return null;
  492.         }
  493.         return $this->em->getPharmonlineEm()
  494.             ->getRepository(\App\EntityPharmonline\Pharmacies::class)
  495.             ->find($pharmacy['id']);
  496.     }
  497.     /**
  498.      * Add billing information into cart session
  499.      *
  500.      * @param OrderBillingModel $data
  501.      * @return void
  502.      */
  503.     public function setBillingInformation(OrderBillingModel $orderBilling): void
  504.     {
  505.         $serialized $this->serializer->serialize($orderBilling'json', ['groups' => 'order_billing']);
  506.         $unserializedBillling json_decode($serializedtrue512JSON_THROW_ON_ERROR);
  507.         $session $this->requestStack->getSession();
  508.         $session->set(SessionConstant::CART_BILLING$unserializedBillling);
  509.     }
  510.     /**
  511.      * Get billing information from cart session
  512.      *
  513.      * @return OrderBillingModel|null
  514.      * @throws \JsonException
  515.      */
  516.     public function getBillingInformation(): OrderBillingModel|null
  517.     {
  518.         $session $this->requestStack->getSession();
  519.         if ($session->has(SessionConstant::CART_BILLING)) {
  520.             $data $session->get(SessionConstant::CART_BILLING);
  521.             return $this->serializer->deserialize(
  522.                 json_encode($dataJSON_THROW_ON_ERROR),
  523.                 OrderBillingModel::class,
  524.                 'json'
  525.             );
  526.         }
  527.         return null;
  528.     }
  529.     /**
  530.      * Verify if user can handle current step
  531.      *
  532.      * @return RedirectResponse
  533.      */
  534.     public function verifyStepValidity(): RedirectResponse|null
  535.     {
  536.         $request $this->requestStack->getMainRequest();
  537.         $currentRoute $request->get('_route');
  538.         /** @var FlashBagInterface $flashBag */
  539.         $flashBag $this->requestStack->getSession()->getBag('flashes');
  540.         $session $this->requestStack->getSession();
  541.         if (count($this->getCartFromSession()) < 1) {
  542.             $flashBag->add('error'$this->translator->trans("Votre panier est vide"));
  543.             return new RedirectResponse($this->urlGenerator->generate('app_cart'));
  544.         }
  545.         $redirectArray = [
  546.             'step2' => function () use ($flashBag) {
  547.                 $flashBag->add('error'$this->translator->trans("Vous devez ajouter une pharmacie"));
  548.                 return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP2_ROUTE));
  549.             },
  550. //            'step3' => function () use ($flashBag) {
  551. //                $flashBag->add('error', $this->translator->trans("Vous devez remplir les informations pour la facturation"));
  552. //                return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP3_ROUTE));
  553. //            },
  554. //            'step4' => function () use ($flashBag) {
  555. //                $flashBag->add('error', $this->translator->trans("Vous devez choisir une mode de livraison"));
  556. //                return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP4_ROUTE));
  557. //            },
  558.             'step5' => function () use ($flashBag) {
  559.                 $flashBag->add('error'$this->translator->trans("Vous devez choisir un mode paiement"));
  560.                 return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP5_ROUTE));
  561.             }
  562.         ];
  563.         $user $this->security->getUser();
  564.         if ($currentRoute !== OrderConstant::ORDER_STEP1_ROUTE && !$user) {
  565.             $flashBag->add('error'$this->translator->trans("Vous devez Ãªtre connecter avant de continuer votre commande"));
  566.             return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP1_ROUTE));
  567.         }
  568.         if ($user) {
  569.             if (!$session->has(SessionConstant::CART_PHARMACY) && $currentRoute !== OrderConstant::ORDER_STEP2_ROUTE) {
  570.                 return $redirectArray['step2']();
  571.             }
  572.             if ($currentRoute === OrderConstant::ORDER_STEP4_ROUTE) {
  573. //                if (!$session->has(SessionConstant::CART_BILLING)) {
  574. //                    return $redirectArray['step3']();
  575. //                }
  576.             }
  577.             if ($currentRoute === OrderConstant::ORDER_STEP5_ROUTE) {
  578. //                if (!$session->has(SessionConstant::CART_BILLING)) {
  579. //                    return $redirectArray['step3']();
  580. //                }
  581. //                if (!$session->has(SessionConstant::CART_SHIPPING)) {
  582. //                    return $redirectArray['step4']();
  583. //                }
  584.             }
  585.             if ($currentRoute === OrderConstant::ORDER_STEP6_ROUTE) {
  586. //                if (!$session->has(SessionConstant::CART_BILLING)) {
  587. //                    return $redirectArray['step3']();
  588. //                }
  589. //                if (!$session->has(SessionConstant::CART_SHIPPING)) {
  590. //                    return $redirectArray['step4']();
  591. //                }
  592.                 if (!$session->has(SessionConstant::CART_PAYMENT)) {
  593.                     return $redirectArray['step5']();
  594.                 }
  595.             }
  596.         }
  597.         return null;
  598.     }
  599.     /**
  600.      * Set cart shipping method
  601.      *
  602.      * @param string $shippingMethod COLLECT_PHARMACY DELIVERY_HOME
  603.      * @return void
  604.      */
  605.     public function setShippingMethod(string $shippingMethod)
  606.     {
  607.         $allowedShippingMethod = [ShippingMethodConstant::COLLECT_PHARMACYShippingMethodConstant::DELIVERY_HOME];
  608.         $session $this->requestStack->getSession();
  609.         if (in_array($shippingMethod$allowedShippingMethodtrue)) {
  610.             $session->set(SessionConstant::CART_SHIPPING$shippingMethod);
  611.         }
  612.     }
  613.     /**
  614.      * Get cart shipping method
  615.      *
  616.      * @return string|null
  617.      */
  618.     public function getShippingMethod(): string|null
  619.     {
  620.         $session $this->requestStack->getSession();
  621.         if ($session->has(SessionConstant::CART_SHIPPING)) {
  622.             return $session->get(SessionConstant::CART_SHIPPING);
  623.         }
  624.         return null;
  625.     }
  626.     /**
  627.      * Add method payement method
  628.      *
  629.      * @param mixed $get
  630.      * @return void
  631.      */
  632.     public function setPayment(string $payment)
  633.     {
  634.         $allowedPayment = [PaymentConstant::COLLECT_PAYMENT];
  635.         $session $this->requestStack->getSession();
  636.         if (in_array($payment$allowedPaymenttrue)) {
  637.             $session->set(SessionConstant::CART_PAYMENT$payment);
  638.         }
  639.     }
  640.     /**
  641.      * Get payment from session
  642.      *
  643.      * @return string|null
  644.      */
  645.     public function getPayment(): string|null
  646.     {
  647.         $session $this->requestStack->getSession();
  648.         if ($session->has(SessionConstant::CART_PAYMENT)) {
  649.             return $session->get(SessionConstant::CART_PAYMENT);
  650.         }
  651.         return null;
  652.     }
  653.     /**
  654.      * Generate Order entity from session data
  655.      *
  656.      * @return Orders
  657.      * @throws \JsonException
  658.      */
  659.     public function generateOrderEntity(): Orders
  660.     {
  661.         $order = new Orders();
  662.         /** @var Users $user */
  663.         $user $this->security->getUser();
  664.         $cart $this->getHydratedCartNoSerializable();
  665.         $pharmacy $this->getPharmacyHydrated();
  666.         $shipping $this->getShippingMethod();
  667.         $billingInformation $this->getBillingInformation();
  668.         $promotionalCode $this->getCouponCode();
  669.         $total $this->getTotalBrut();
  670.         // ADD CART GIFT
  671.         $cartGifts $this->orderGiftRepository->findProductGift(nulltrue$total);
  672.         foreach ($cartGifts as $gift) {
  673.             $order->addOrderGift($gift);
  674.         }
  675.         /**
  676.          * Add product in order entity
  677.          */
  678.         foreach ($cart as $cartItem) {
  679.             /** @var Products $product */
  680.             $product $cartItem['product'];
  681.             // Get all gift related with this product
  682.             $productGifts $this->orderGiftRepository->findProductGift($producttrue$total);
  683.             foreach ($productGifts as $gift) {
  684.                 $order->addOrderGift($gift);
  685.             }
  686.             $pharmacyProduct = (new PharmaciesProducts())->setProduct($product)
  687.                 ->setPrice($product->getPrice())
  688.                 ->setPharmacyId($pharmacy->getId());
  689.             $orderProduct = (new OrdersProducts())->setPharmaciesProducts($pharmacyProduct)
  690.                 ->setQuantity($cartItem['quantity'])
  691.                 ->setTotal($cartItem['total'])
  692.                 ->setUnitPrice($cartItem['price']);
  693.             /** @var ProductsAttributsTerms $attribut */
  694.             if ($attribut $cartItem['attribut']) {
  695.                 $text $this->serializer->serialize($attribut'json', ['groups' => 'productAttributTerm']);
  696.                 $orderProduct->setAttributText($text);
  697.                 if ($attribut->getPrice()) {
  698.                     $orderProduct->setUnitPrice($attribut->getPrice());
  699.                 }
  700.             }
  701.             /**
  702.              * Handle prestation
  703.              */
  704.             if (is_array($cartItem['prestation'])) {
  705.                 $prestation $cartItem['prestation'];
  706.                 $newOrderPrestation = (new OrdersPrestations())
  707.                     ->setPharmacyPrestationId($prestation['pharmacyPrestation']->getId())
  708.                     ->setPrestationId($prestation['productPrestation']->getPrestationId())
  709.                     ->setPrice($prestation['price'] ?? 0)
  710.                     ->setStatus(OrderPrestationStatusType::WAIT);
  711.                 $order->addOrdersPrestation($newOrderPrestation);
  712.             }
  713.             $order->addOrdersProduct($orderProduct);
  714.         }
  715.         /**
  716.          * Shipping and billing
  717.          */
  718.         $shippingOrderTypePharmacy array_filter($pharmacy->getShippingMethods(), function ($pharmacyShipping) use ($shipping) {
  719.             return $pharmacyShipping->getShippingMethod()->getType() === $shipping;
  720.         });
  721.         if (count($shippingOrderTypePharmacy) > 0) {
  722.             $order->setShippingType($shippingOrderTypePharmacy[0])
  723.                 ->setInvoceName(sprintf("%s %s"$billingInformation?->getLastname(), $billingInformation?->getFirstname()))
  724.                 ->setInvodeAddress($billingInformation?->getAddress())
  725.                 ->setInvocePostcode($billingInformation?->getPostcode())
  726.                 ->setInvoceCity($billingInformation?->getCity())
  727.                 ->setShippingPostcode($user->getPostcode())
  728.                 ->setShippingAddress($user->getAddress())
  729.                 ->setShippingCity($user->getLocation())
  730.                 ->setShippingName($user->getName());
  731.         }
  732.         /**
  733.          * Promo code
  734.          */
  735.         foreach ($promotionalCode as $promo) {
  736.             $ref $promo['ref'];
  737.             $promoCodeEntity $this->em->getEm()
  738.                 ->getRepository(PromotionalCode::class)
  739.                 ->findOneBy(['reference' => $ref]);
  740.             if ($promoCodeEntity) {
  741.                 $order->addPromotionalCode($promoCodeEntity);
  742.             }
  743.         }
  744.         /**
  745.          * Payment
  746.          */
  747.         $payment $this->getPayment();
  748. //        $pharmacyPayment = array_filter($pharmacy->getPaymentMethods(), function ($pharmacyPayment) use ($payment) {
  749. //            return $pharmacyPayment->getPaymentMethod()->getType() === $payment;
  750. //        });
  751. //        $order->setPaymentMethod($pharmacyPayment[0])
  752.         $order
  753.             ->setIsDone(false)
  754.             ->setStatus(OrderStatusType::INIT)
  755.             ->setPrice($total)
  756.             ->setPharmacyId($pharmacy->getId())
  757.             ->setUserId($user->getId());
  758.         return $order;
  759.     }
  760.     /**
  761.      * Clear cart in session
  762.      *
  763.      * @return void
  764.      */
  765.     public function clearCartSession(): void
  766.     {
  767.         $session $this->requestStack->getSession();
  768.         $session->remove(SessionConstant::CART);
  769.         $session->remove(SessionConstant::CART_PAYMENT);
  770.         $session->remove(SessionConstant::CART_SHIPPING);
  771.         $session->remove(SessionConstant::CART_BILLING);
  772.         $session->remove(SessionConstant::CART_PHARMACY);
  773.         $session->remove(SessionConstant::COUPONS_CODE);
  774.     }
  775.     /**
  776.      * Handle add prestation and prestation price in cart
  777.      * If we have no content, we reset all product prestation to null
  778.      *
  779.      * @param array $content
  780.      * [
  781.      *  [
  782.      *      "prestations" => 1
  783.      *      "productId" => 250
  784.      *      "pharmacyServiceId" => 6002
  785.      *  ]
  786.      * ]
  787.      * @return void
  788.      */
  789.     public function handleAddPrestations(array $content): void
  790.     {
  791.         if (count($content) < 1) {
  792.             $this->handlePrestationNullAllProduct();
  793.             return;
  794.         }
  795.         $repository $this->em->getEm()->getRepository(ProductsPrestations::class);
  796.         $productRepository $this->em->getEm()->getRepository(Products::class);
  797.         $pharmacyPrestationRepository $this->em->getPharmonlineEm()->getRepository(PharmaciesServices::class);
  798.         $cart $this->getCartFromSession();
  799.         foreach ($cart as $key => $cartProduct) {
  800.             $cartProduct['prestation'] = null;
  801.             foreach ($content as $item) {
  802.                 $product $productRepository->find($item['productId']);
  803.                 $productPrestation $repository->findOneBy(['prestationId' => $item['prestations'], 'product' => $product]);
  804.                 $pharmacyPrestation $pharmacyPrestationRepository->find($item['pharmacyServiceId']);
  805.                 if ($cartProduct['product'] === $product->getId()) {
  806.                     $prestationPrice $productPrestation->getPrestation()->getActiveShopPrice()
  807.                         ? $productPrestation->getPrestation()->getShopPrice()
  808.                         : $pharmacyPrestation->getPrice();
  809.                     $cartProduct['prestation'] = [
  810.                         'productPrestation' => (int)$productPrestation->getId(),
  811.                         'pharmacyPrestation' => (int)$item['pharmacyServiceId'],
  812.                         'price' => (float)$prestationPrice
  813.                     ];
  814.                 }
  815.             }
  816.             $cart[$key] = $cartProduct;
  817.         }
  818.         $session $this->requestStack->getSession();
  819.         $session->set(SessionConstant::CART$cart);
  820.     }
  821.     /**
  822.      * If we send null prestation
  823.      * We update all product to have null prestation
  824.      *
  825.      * @return void
  826.      */
  827.     private function handlePrestationNullAllProduct(): void
  828.     {
  829.         $cart $this->getCartFromSession();
  830.         foreach ($cart as $key => $productCart) {
  831.             $productCart['prestation'] = null;
  832.             $cart[$key] = $productCart;
  833.         }
  834.         $session $this->requestStack->getSession();
  835.         $session->set(SessionConstant::CART$cart);
  836.     }
  837.     /**
  838.      * Get all cart prestation to show in cart resume
  839.      *
  840.      * @return array
  841.      */
  842.     public function getCartPrestation(): array
  843.     {
  844.         $cart $this->getHydratedCartNoSerializable();
  845.         $result = [];
  846.         foreach ($cart as $cartProduct) {
  847.             if (is_array($cartProduct['prestation'])) {
  848.                 $result[] = $cartProduct['prestation'];
  849.             }
  850.         }
  851.         return $result;
  852.     }
  853.     /**
  854.      * Get all cart prestation to show in cart resume
  855.      *
  856.      * @return array
  857.      */
  858.     public function getCartPrestationSerialized(): array
  859.     {
  860.         $cart $this->getHydratedCartNoSerializable();
  861.         $result = [];
  862.         foreach ($cart as $cartProduct) {
  863.             if (is_array($cartProduct['prestation'])) {
  864.                 $result[] = [
  865.                     "productPrestation" => (int)$cartProduct['prestation']['productPrestation']->getId(),
  866.                     "pharmacyPrestation" => (int)$cartProduct['prestation']['pharmacyPrestation']->getId(),
  867.                 ];
  868.             }
  869.         }
  870.         return $result;
  871.     }
  872.     /**
  873.      * Send notification into pharmacy for new order
  874.      *
  875.      * @param Orders $order
  876.      * @return void
  877.      */
  878.     public function sendNotification(Orders $order): void
  879.     {
  880.         $notification = (new PharmacyNotification())
  881.             ->setType(NotificationConstant::NEW_ORDER)
  882.             ->setOrders($order)
  883.             ->setPharmacyId($order->getPharmacyId());
  884.         $this->em->save($notification);
  885.     }
  886. }