<?php
/**
* @author <akartis-dev>
*/
namespace App\Service\Cart;
use App\Doctrine\Type\Order\OrderPrestationStatusType;
use App\Doctrine\Type\Order\OrderStatusType;
use App\Doctrine\Type\PromotionalCode\PromotionalCodeType;
use App\Entity\Orders\Orders;
use App\Entity\Orders\OrdersPrestations;
use App\Entity\Orders\OrdersProducts;
use App\Entity\Pharmacies\PharmaciesProducts;
use App\Entity\PharmacyNotification;
use App\Entity\Products\Attribut\ProductsAttributsTerms;
use App\Entity\Products\Products;
use App\Entity\Products\ProductsPrestations;
use App\Entity\PromotionalCode\PromotionalCode;
use App\EntityPharmonline\PharmaciesServices;
use App\EntityPharmonline\Users;
use App\Exception\PromoCodeException;
use App\Form\Orders\OrderBillingModel;
use App\Kernel;
use App\ObjectManager\EntityObjectManager;
use App\Repository\Gift\OrderGiftRepository;
use App\Repository\Pharmacies\PharmaciesRepository;
use App\Repository\Products\Attribut\ProductsAttributsTermsRepository;
use App\Repository\Products\ProductsRepository;
use App\Service\Constant\NotificationConstant;
use App\Service\Constant\OrderConstant;
use App\Service\Constant\PaymentConstant;
use App\Service\Constant\SessionConstant;
use App\Service\Constant\ShippingMethodConstant;
use App\Service\Gift\GiftService;
use App\Service\Mailer\UserMailer;
use App\Service\PromotionalCode\PromotionalCodeService;
use JetBrains\PhpStorm\ArrayShape;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class CartService
{
public function __construct(
private RequestStack $requestStack,
private ProductsRepository $productsRepository,
private PharmaciesRepository $pharmaciesRepository,
private ProductsAttributsTermsRepository $productsAttributsTermsRepository,
private SerializerInterface $serializer,
private Kernel $kernel,
private EntityObjectManager $em,
private UrlGeneratorInterface $urlGenerator,
private Security $security,
private TranslatorInterface $translator,
private OrderGiftRepository $orderGiftRepository,
private UserMailer $userMailer
)
{
}
/**
* Add or increment product in cart
*
* @param int $productId
* @param int|null $pharmacyId
* @param int|null $attributId
* @param int|null $quantity
* @return bool
*/
public function addInCart(int $productId, ?int $pharmacyId, ?int $attributId, ?int $quantity): bool
{
$currentCart = $this->getCartFromSession();
$product = $this->productsRepository->find($productId);
if (!$product) {
return false;
}
$containAttribut = $product->getProductsAttributsTerms()
->filter(
function (ProductsAttributsTerms $productsAttributsTerms) use ($attributId) {
return $productsAttributsTerms->getId() === $attributId;
}
);
$this->updateProductInCartSession(
product: $product,
pharmaciesProducts: null,
attributsTerms: $containAttribut->first(),
quantity: $quantity
);
return true;
}
/**
* Get cart from session
*
*/
private function getCartFromSession(): array
{
$session = $this->requestStack->getSession();
if (!$session->has(SessionConstant::CART)) {
$session->set(SessionConstant::CART, []);
return [];
}
return $session->get(SessionConstant::CART);
}
/**
* Get coupon code from session
*
*/
private function getCouponFromSession(): array
{
$session = $this->requestStack->getSession();
if (!$session->has(SessionConstant::COUPONS_CODE)) {
$session->set(SessionConstant::COUPONS_CODE, []);
return [];
}
return $session->get(SessionConstant::COUPONS_CODE);
}
/**
* Create new product in session cart
* Update quantity and price total if already present
*
* @param Products $product
* @param int|null $pharmacyId
* @param int|null $attributId
*/
#[ArrayShape(['product' => "int|null", 'pharmacy' => "int|null", 'attribut' => "int|null", 'price' => "int", "quantity" => "int", "total" => "int"])]
private function updateProductInCartSession(
Products $product,
?PharmaciesProducts $pharmaciesProducts,
ProductsAttributsTerms|bool $attributsTerms,
int $quantity
): void
{
$cart = $this->getCartFromSession();
$price = $product->inPromotion() ? $product->getPriceWithPromotion() : $product->getPrice();
$session = $this->requestStack->getSession();
$attributId = $attributsTerms ? $attributsTerms->getId() : 0;
if (
$attributsTerms &&
$attributsTerms->getPrice() &&
$attributsTerms->getPrice() > 0
) {
$pourcentPromotion = number_format(100 - ($product->getPriceWithPromotion() * 100 / $product->getPrice()), 0);
$price = $attributsTerms->getPrice() * (1 - ((int)$pourcentPromotion / 100));
}
$alreadyPresent = false;
foreach ($cart as $key => $cartProduct) {
if ($cartProduct['product'] === $product->getId() && $cartProduct['attribut'] === $attributId) {
$quantity = $cartProduct['quantity'] + $quantity;
$cartProduct['quantity'] = $quantity;
$cartProduct['total'] = $cartProduct['price'] * $quantity;
$alreadyPresent = true;
$cart[$key] = $cartProduct;
}
}
if (!$alreadyPresent) {
$cart[] = [
'product' => $product->getId(),
'pharmacy' => $pharmaciesProducts ? $pharmaciesProducts->getPharmacy()->getId() : 0,
'attribut' => $attributId,
'price' => $price,
"quantity" => $quantity ?? 1,
"total" => $price * $quantity,
"promotion" => 0,
'prestation' => null
];
}
$session->set(SessionConstant::CART, $cart);
$session->save();
}
/**
* Add a new coupon code in session
*
* @param PromotionalCode $promoCode
* @return bool
*/
public function addCouponCode(PromotionalCode $promoCode): bool
{
$session = $this->requestStack->getSession();
$couponCode = $this->getCouponCode();
$data = [
'ref' => $promoCode->getReference(),
'type' => $promoCode->getType(),
'discount' => $promoCode->getPromoDiscount(),
'combine' => $promoCode->getCombineOtherCoupons()
];
$alreadyExist = false;
foreach ($couponCode as $coupon) {
if ($coupon['ref'] === $promoCode->getReference()) {
$alreadyExist = true;
break;
}
}
if (!$alreadyExist) {
$couponCode[] = $data;
$session->set(SessionConstant::COUPONS_CODE, $couponCode);
$session->save();
}
return $alreadyExist;
}
/**
* Remove product in session cart
*
* @param int $productId
* @return array
*/
public function subProductInSessionCart(int $productId, ?int $attribut, bool $all = false): array|bool
{
$currentCart = $this->getCartFromSession();
$product = $this->productsRepository->find($productId);
if (!$product) {
return false;
}
foreach ($currentCart as $key => $cartItem) {
if ((int)$cartItem['product'] === $product->getId()) {
$quantity = $all ? 0 : $cartItem['quantity'] - 1;
if ($attribut === 0) {
$currentCart[$key]['quantity'] = $quantity;
$currentCart[$key]['total'] = $cartItem['price'] * $quantity;
} else if ($attribut === $cartItem['attribut']) {
$currentCart[$key]['quantity'] = $quantity;
$currentCart[$key]['total'] = $cartItem['price'] * $quantity;
}
}
}
$prestations = $this->getCartPrestation();
foreach ($currentCart as $key => $cartItem) {
if ($cartItem['quantity'] <= 0) {
/** Remove attached prestation */
foreach ($prestations as $prestationKey => $prestation) {
if ($prestation['productPrestation']->getProduct()->getId() === $cartItem['product']) {
unset($prestations[$prestationKey]);
break;
}
}
unset($currentCart[$key]);
}
}
$reassignedPrestation = array_map(static function ($item) {
return [
"prestations" => (int)$item['productPrestation']->getPrestationId(),
"productId" => (int)$item['productPrestation']->getProduct()->getId(),
"pharmacyServiceId" => (int)$item['pharmacyPrestation']->getId()
];
}, $prestations);
$this->handleAddPrestations($reassignedPrestation);
$this->reassignAllCartInSession($currentCart);
return $this->reverifyCouponCartUpdated();
}
/**
* Get cart with related entity
*
* @return array
* @throws \JsonException
*/
public
function getHydratedCart(): array
{
$currentCart = $this->getCartFromSession();
$results = [];
foreach ($currentCart as $cartItem) {
$product = $this->serializer->serialize(
$this->productsRepository->find($cartItem['product']), 'json', ['groups' => 'product']
);
$pharmacy = $this->serializer->serialize(
$this->pharmaciesRepository->find($cartItem['pharmacy']), 'json', ['groups' => 'pharmacy']
);
$attribut = $this->serializer->serialize(
$this->productsAttributsTermsRepository->find($cartItem['attribut']), 'json', ['groups' => 'productAttributTerm']
);
$item = [
'product' => json_decode($product, true, 512, JSON_THROW_ON_ERROR),
'pharmacy' => json_decode($pharmacy, true, 512, JSON_THROW_ON_ERROR),
'attribut' => json_decode($attribut, true, 512, JSON_THROW_ON_ERROR),
'price' => $cartItem['price'],
"quantity" => $cartItem['quantity'],
"total" => $cartItem['total'],
"promotion" => $cartItem['promotion'],
"prestation" => null
];
if (is_array($cartItem['prestation'] ?? null)) {
$data = [
'productPrestation' => $cartItem['prestation']['productPrestation'],
"pharmacyPrestation" => $cartItem['prestation']['pharmacyPrestation'],
"price" => $cartItem['prestation']['price'],
];
$item['prestation'] = $data;
}
$results[] = $item;
}
return $results;
}
/**
* Get cart with related entity not serialized
*
* @return array<string, array{
* 'product' => Products::class,
* 'pharmacy' => Pharmacies::class | null,
* 'attribut' => ProductsAttributsTerms::class | null,
* 'price' => "int",
* "quantity" => "int",
* "total" => "int"
* }>
* @throws \JsonException
*/
public function getHydratedCartNoSerializable(): array
{
$productPrestationRepository = $this->em->getEm()->getRepository(ProductsPrestations::class);
$pharmacyPrestationRepository = $this->em->getPharmonlineEm()->getRepository(PharmaciesServices::class);
$currentCart = $this->getCartFromSession();
$results = [];
foreach ($currentCart as $cartItem) {
$item = [
'product' => $this->productsRepository->findOneBy(['id' => $cartItem['product']]),
'pharmacy' => $this->pharmaciesRepository->find($cartItem['pharmacy']),
'attribut' => $this->productsAttributsTermsRepository->find($cartItem['attribut']),
'price' => $cartItem['price'],
"quantity" => $cartItem['quantity'],
"total" => $cartItem['total'],
"promotion" => $cartItem['promotion'],
"prestation" => null
];
if (is_array($cartItem['prestation'] ?? null)) {
$data = [
'productPrestation' => $productPrestationRepository->find($cartItem['prestation']['productPrestation']),
"pharmacyPrestation" => $pharmacyPrestationRepository->find($cartItem['prestation']['pharmacyPrestation']),
"price" => $cartItem['prestation']['price'],
];
$item['prestation'] = $data;
}
$results[] = $item;
}
return $results;
}
/**
* Get all coupon code for this order
*
* @return array[
* 'ref' => string,
* 'type' => string,
* 'discount' => int
* ]
*
*/
public function getCouponCode(): array
{
return $this->getCouponFromSession();
}
/**
* Get cart total with all coupon
*
* @return string
* @throws \JsonException
*/
public function getCartTotalWithCoupon(): string
{
$coupons = $this->getCouponCode();
$cart = $this->getHydratedCart();
$total = $this->getTotalBrut();
foreach ($coupons as $coupon) {
if ($coupon['type'] === PromotionalCodeType::AMOUNT) {
$total -= $coupon['discount'];
}
if ($coupon['type'] === PromotionalCodeType::PERCENT) {
$total -= ($total * $coupon['discount'] / 100);
}
}
return number_format($total, 2) . " CHF";
}
/**
* Get cart total no coupon
*
* @return string
* @throws \JsonException
*/
public function getCartTotal(): string
{
$total = $this->getTotalBrut();
return number_format($total, 2) . " CHF";
}
/**
* Get brut cart total
*
* @return float
* @throws \JsonException
*/
public function getTotalBrut(): float
{
$coupons = $this->getCouponCode();
$cart = $this->getHydratedCart();
$total = 0;
foreach ($cart as $item) {
$total += $item['total'] - $item['promotion'];
if (is_array($item["prestation"])) {
$total += $item['prestation']['price'] ?? 0;
}
}
return $total;
}
/**
* Re-verify all coupon when cart is updated
*
* @return array
* @throws \JsonException
*/
public function reverifyCouponCartUpdated(): array
{
/**
* To avoid circular reference injected
*/
$promotionalCodeService = $this->kernel->getContainer()->get(PromotionalCodeService::class);
$coupons = $this->getCouponCode();
$this->reassignAllCouponInSession([]);
$removedCoupon = [];
foreach ($coupons as $coupon) {
try {
$promotionalCodeService->verify($coupon['ref']);
} catch (PromoCodeException $promoCodeException) {
$removedCoupon[] = $coupon['ref'];
}
}
$filteredCoupon = array_filter($coupons, function ($coupon) use ($removedCoupon) {
return !in_array($coupon['ref'], $removedCoupon, true);
});
$this->reassignAllCouponInSession($filteredCoupon);
return $removedCoupon;
}
/**
* Reassign all coupon in session
*
* @param array $coupons
* @return void
*/
public function reassignAllCouponInSession(array $coupons): void
{
$session = $this->requestStack->getSession();
$session->set(SessionConstant::COUPONS_CODE, $coupons);
$session->save();
}
/**
* Reassign all cart in session
*
* @param array $coupons
* @return void
*/
public function reassignAllCartInSession(array $cart): void
{
$session = $this->requestStack->getSession();
$session->set(SessionConstant::CART, $cart);
$session->save();
}
/**
* Set pharmacy in cart
*
* @return bool
* @throws \JsonException
*/
public function setPharmacyCart(int $pharmacyId): bool
{
$pharmacy = $this->em->getPharmonlineEm()->getRepository(\App\EntityPharmonline\Pharmacies::class)->find($pharmacyId);
if ($pharmacy) {
$serializedPharmacy = $this->serializer->serialize($pharmacy, 'json', ['groups' => 'pharmacy']);
$session = $this->requestStack->getSession();
$session->set(SessionConstant::CART_PHARMACY, json_decode($serializedPharmacy, true, 512, JSON_THROW_ON_ERROR));
$session->save();
return true;
}
return false;
}
/**
* Get pharmacy cart from session
* @return mixed|null
*/
public function getPharmacyCart(): null|array
{
$session = $this->requestStack->getSession();
if (!$session->has(SessionConstant::CART_PHARMACY)) {
return null;
}
return $session->get(SessionConstant::CART_PHARMACY);
}
/**
* Get pharmacy cart entity
*
* @return \App\EntityPharmonline\Pharmacies|null
*/
public function getPharmacyHydrated(): \App\EntityPharmonline\Pharmacies|null
{
$pharmacy = $this->getPharmacyCart();
if (!$pharmacy) {
return null;
}
return $this->em->getPharmonlineEm()
->getRepository(\App\EntityPharmonline\Pharmacies::class)
->find($pharmacy['id']);
}
/**
* Add billing information into cart session
*
* @param OrderBillingModel $data
* @return void
*/
public function setBillingInformation(OrderBillingModel $orderBilling): void
{
$serialized = $this->serializer->serialize($orderBilling, 'json', ['groups' => 'order_billing']);
$unserializedBillling = json_decode($serialized, true, 512, JSON_THROW_ON_ERROR);
$session = $this->requestStack->getSession();
$session->set(SessionConstant::CART_BILLING, $unserializedBillling);
}
/**
* Get billing information from cart session
*
* @return OrderBillingModel|null
* @throws \JsonException
*/
public function getBillingInformation(): OrderBillingModel|null
{
$session = $this->requestStack->getSession();
if ($session->has(SessionConstant::CART_BILLING)) {
$data = $session->get(SessionConstant::CART_BILLING);
return $this->serializer->deserialize(
json_encode($data, JSON_THROW_ON_ERROR),
OrderBillingModel::class,
'json'
);
}
return null;
}
/**
* Verify if user can handle current step
*
* @return RedirectResponse
*/
public function verifyStepValidity(): RedirectResponse|null
{
$request = $this->requestStack->getMainRequest();
$currentRoute = $request->get('_route');
/** @var FlashBagInterface $flashBag */
$flashBag = $this->requestStack->getSession()->getBag('flashes');
$session = $this->requestStack->getSession();
if (count($this->getCartFromSession()) < 1) {
$flashBag->add('error', $this->translator->trans("Votre panier est vide"));
return new RedirectResponse($this->urlGenerator->generate('app_cart'));
}
$redirectArray = [
'step2' => function () use ($flashBag) {
$flashBag->add('error', $this->translator->trans("Vous devez ajouter une pharmacie"));
return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP2_ROUTE));
},
// 'step3' => function () use ($flashBag) {
// $flashBag->add('error', $this->translator->trans("Vous devez remplir les informations pour la facturation"));
// return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP3_ROUTE));
// },
// 'step4' => function () use ($flashBag) {
// $flashBag->add('error', $this->translator->trans("Vous devez choisir une mode de livraison"));
// return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP4_ROUTE));
// },
'step5' => function () use ($flashBag) {
$flashBag->add('error', $this->translator->trans("Vous devez choisir un mode paiement"));
return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP5_ROUTE));
}
];
$user = $this->security->getUser();
if ($currentRoute !== OrderConstant::ORDER_STEP1_ROUTE && !$user) {
$flashBag->add('error', $this->translator->trans("Vous devez être connecter avant de continuer votre commande"));
return new RedirectResponse($this->urlGenerator->generate(OrderConstant::ORDER_STEP1_ROUTE));
}
if ($user) {
if (!$session->has(SessionConstant::CART_PHARMACY) && $currentRoute !== OrderConstant::ORDER_STEP2_ROUTE) {
return $redirectArray['step2']();
}
if ($currentRoute === OrderConstant::ORDER_STEP4_ROUTE) {
// if (!$session->has(SessionConstant::CART_BILLING)) {
// return $redirectArray['step3']();
// }
}
if ($currentRoute === OrderConstant::ORDER_STEP5_ROUTE) {
// if (!$session->has(SessionConstant::CART_BILLING)) {
// return $redirectArray['step3']();
// }
// if (!$session->has(SessionConstant::CART_SHIPPING)) {
// return $redirectArray['step4']();
// }
}
if ($currentRoute === OrderConstant::ORDER_STEP6_ROUTE) {
// if (!$session->has(SessionConstant::CART_BILLING)) {
// return $redirectArray['step3']();
// }
// if (!$session->has(SessionConstant::CART_SHIPPING)) {
// return $redirectArray['step4']();
// }
if (!$session->has(SessionConstant::CART_PAYMENT)) {
return $redirectArray['step5']();
}
}
}
return null;
}
/**
* Set cart shipping method
*
* @param string $shippingMethod COLLECT_PHARMACY DELIVERY_HOME
* @return void
*/
public function setShippingMethod(string $shippingMethod)
{
$allowedShippingMethod = [ShippingMethodConstant::COLLECT_PHARMACY, ShippingMethodConstant::DELIVERY_HOME];
$session = $this->requestStack->getSession();
if (in_array($shippingMethod, $allowedShippingMethod, true)) {
$session->set(SessionConstant::CART_SHIPPING, $shippingMethod);
}
}
/**
* Get cart shipping method
*
* @return string|null
*/
public function getShippingMethod(): string|null
{
$session = $this->requestStack->getSession();
if ($session->has(SessionConstant::CART_SHIPPING)) {
return $session->get(SessionConstant::CART_SHIPPING);
}
return null;
}
/**
* Add method payement method
*
* @param mixed $get
* @return void
*/
public function setPayment(string $payment)
{
$allowedPayment = [PaymentConstant::COLLECT_PAYMENT];
$session = $this->requestStack->getSession();
if (in_array($payment, $allowedPayment, true)) {
$session->set(SessionConstant::CART_PAYMENT, $payment);
}
}
/**
* Get payment from session
*
* @return string|null
*/
public function getPayment(): string|null
{
$session = $this->requestStack->getSession();
if ($session->has(SessionConstant::CART_PAYMENT)) {
return $session->get(SessionConstant::CART_PAYMENT);
}
return null;
}
/**
* Generate Order entity from session data
*
* @return Orders
* @throws \JsonException
*/
public function generateOrderEntity(): Orders
{
$order = new Orders();
/** @var Users $user */
$user = $this->security->getUser();
$cart = $this->getHydratedCartNoSerializable();
$pharmacy = $this->getPharmacyHydrated();
$shipping = $this->getShippingMethod();
$billingInformation = $this->getBillingInformation();
$promotionalCode = $this->getCouponCode();
$total = $this->getTotalBrut();
// ADD CART GIFT
$cartGifts = $this->orderGiftRepository->findProductGift(null, true, $total);
foreach ($cartGifts as $gift) {
$order->addOrderGift($gift);
}
/**
* Add product in order entity
*/
foreach ($cart as $cartItem) {
/** @var Products $product */
$product = $cartItem['product'];
// Get all gift related with this product
$productGifts = $this->orderGiftRepository->findProductGift($product, true, $total);
foreach ($productGifts as $gift) {
$order->addOrderGift($gift);
}
$pharmacyProduct = (new PharmaciesProducts())->setProduct($product)
->setPrice($product->getPrice())
->setPharmacyId($pharmacy->getId());
$orderProduct = (new OrdersProducts())->setPharmaciesProducts($pharmacyProduct)
->setQuantity($cartItem['quantity'])
->setTotal($cartItem['total'])
->setUnitPrice($cartItem['price']);
/** @var ProductsAttributsTerms $attribut */
if ($attribut = $cartItem['attribut']) {
$text = $this->serializer->serialize($attribut, 'json', ['groups' => 'productAttributTerm']);
$orderProduct->setAttributText($text);
if ($attribut->getPrice()) {
$orderProduct->setUnitPrice($attribut->getPrice());
}
}
/**
* Handle prestation
*/
if (is_array($cartItem['prestation'])) {
$prestation = $cartItem['prestation'];
$newOrderPrestation = (new OrdersPrestations())
->setPharmacyPrestationId($prestation['pharmacyPrestation']->getId())
->setPrestationId($prestation['productPrestation']->getPrestationId())
->setPrice($prestation['price'] ?? 0)
->setStatus(OrderPrestationStatusType::WAIT);
$order->addOrdersPrestation($newOrderPrestation);
}
$order->addOrdersProduct($orderProduct);
}
/**
* Shipping and billing
*/
$shippingOrderTypePharmacy = array_filter($pharmacy->getShippingMethods(), function ($pharmacyShipping) use ($shipping) {
return $pharmacyShipping->getShippingMethod()->getType() === $shipping;
});
if (count($shippingOrderTypePharmacy) > 0) {
$order->setShippingType($shippingOrderTypePharmacy[0])
->setInvoceName(sprintf("%s %s", $billingInformation?->getLastname(), $billingInformation?->getFirstname()))
->setInvodeAddress($billingInformation?->getAddress())
->setInvocePostcode($billingInformation?->getPostcode())
->setInvoceCity($billingInformation?->getCity())
->setShippingPostcode($user->getPostcode())
->setShippingAddress($user->getAddress())
->setShippingCity($user->getLocation())
->setShippingName($user->getName());
}
/**
* Promo code
*/
foreach ($promotionalCode as $promo) {
$ref = $promo['ref'];
$promoCodeEntity = $this->em->getEm()
->getRepository(PromotionalCode::class)
->findOneBy(['reference' => $ref]);
if ($promoCodeEntity) {
$order->addPromotionalCode($promoCodeEntity);
}
}
/**
* Payment
*/
$payment = $this->getPayment();
// $pharmacyPayment = array_filter($pharmacy->getPaymentMethods(), function ($pharmacyPayment) use ($payment) {
// return $pharmacyPayment->getPaymentMethod()->getType() === $payment;
// });
// $order->setPaymentMethod($pharmacyPayment[0])
$order
->setIsDone(false)
->setStatus(OrderStatusType::INIT)
->setPrice($total)
->setPharmacyId($pharmacy->getId())
->setUserId($user->getId());
return $order;
}
/**
* Clear cart in session
*
* @return void
*/
public function clearCartSession(): void
{
$session = $this->requestStack->getSession();
$session->remove(SessionConstant::CART);
$session->remove(SessionConstant::CART_PAYMENT);
$session->remove(SessionConstant::CART_SHIPPING);
$session->remove(SessionConstant::CART_BILLING);
$session->remove(SessionConstant::CART_PHARMACY);
$session->remove(SessionConstant::COUPONS_CODE);
}
/**
* Handle add prestation and prestation price in cart
* If we have no content, we reset all product prestation to null
*
* @param array $content
* [
* [
* "prestations" => 1
* "productId" => 250
* "pharmacyServiceId" => 6002
* ]
* ]
* @return void
*/
public function handleAddPrestations(array $content): void
{
if (count($content) < 1) {
$this->handlePrestationNullAllProduct();
return;
}
$repository = $this->em->getEm()->getRepository(ProductsPrestations::class);
$productRepository = $this->em->getEm()->getRepository(Products::class);
$pharmacyPrestationRepository = $this->em->getPharmonlineEm()->getRepository(PharmaciesServices::class);
$cart = $this->getCartFromSession();
foreach ($cart as $key => $cartProduct) {
$cartProduct['prestation'] = null;
foreach ($content as $item) {
$product = $productRepository->find($item['productId']);
$productPrestation = $repository->findOneBy(['prestationId' => $item['prestations'], 'product' => $product]);
$pharmacyPrestation = $pharmacyPrestationRepository->find($item['pharmacyServiceId']);
if ($cartProduct['product'] === $product->getId()) {
$prestationPrice = $productPrestation->getPrestation()->getActiveShopPrice()
? $productPrestation->getPrestation()->getShopPrice()
: $pharmacyPrestation->getPrice();
$cartProduct['prestation'] = [
'productPrestation' => (int)$productPrestation->getId(),
'pharmacyPrestation' => (int)$item['pharmacyServiceId'],
'price' => (float)$prestationPrice
];
}
}
$cart[$key] = $cartProduct;
}
$session = $this->requestStack->getSession();
$session->set(SessionConstant::CART, $cart);
}
/**
* If we send null prestation
* We update all product to have null prestation
*
* @return void
*/
private function handlePrestationNullAllProduct(): void
{
$cart = $this->getCartFromSession();
foreach ($cart as $key => $productCart) {
$productCart['prestation'] = null;
$cart[$key] = $productCart;
}
$session = $this->requestStack->getSession();
$session->set(SessionConstant::CART, $cart);
}
/**
* Get all cart prestation to show in cart resume
*
* @return array
*/
public function getCartPrestation(): array
{
$cart = $this->getHydratedCartNoSerializable();
$result = [];
foreach ($cart as $cartProduct) {
if (is_array($cartProduct['prestation'])) {
$result[] = $cartProduct['prestation'];
}
}
return $result;
}
/**
* Get all cart prestation to show in cart resume
*
* @return array
*/
public function getCartPrestationSerialized(): array
{
$cart = $this->getHydratedCartNoSerializable();
$result = [];
foreach ($cart as $cartProduct) {
if (is_array($cartProduct['prestation'])) {
$result[] = [
"productPrestation" => (int)$cartProduct['prestation']['productPrestation']->getId(),
"pharmacyPrestation" => (int)$cartProduct['prestation']['pharmacyPrestation']->getId(),
];
}
}
return $result;
}
/**
* Send notification into pharmacy for new order
*
* @param Orders $order
* @return void
*/
public function sendNotification(Orders $order): void
{
$notification = (new PharmacyNotification())
->setType(NotificationConstant::NEW_ORDER)
->setOrders($order)
->setPharmacyId($order->getPharmacyId());
$this->em->save($notification);
}
}