/**
  * If the cart's shipping amount is not defined, then put an empty Money
  * value
  *
  * @param CartInterface $cart Cart
  */
 public function validateEmptyShippingAmount(CartInterface $cart)
 {
     $shippingAmount = $cart->getShippingAmount();
     if (!$shippingAmount instanceof MoneyInterface) {
         $cart->setShippingAmount($this->emptyMoneyWrapper->get());
     }
 }
 /**
  * Calculate coupon absolute value.
  *
  * @param CartInterface   $cart   Cart
  * @param CouponInterface $coupon Coupon
  *
  * @return MoneyInterface|false Absolute value for this coupon in this cart
  */
 public function getCouponAbsoluteValue(CartInterface $cart, CouponInterface $coupon)
 {
     $currency = $this->currencyWrapper->get();
     $couponPrice = Money::create(0, $currency);
     $value = $coupon->getValue();
     preg_match($this->regexp(), $value, $match);
     $m = (int) $match[1];
     $n = (int) $match[2];
     $expressionValue = isset($match[3]) ? $match[3] : '';
     $modifiers = isset($match[4]) ? $match[4] : '';
     $freePerGroup = $m - $n;
     $freePerGroup = max($freePerGroup, 0);
     foreach ($cart->getCartLines() as $cartLine) {
         $moneys = [];
         $purchasable = $cartLine->getPurchasable();
         $expressionEvaluator = $this->getExpressionLanguageInstance();
         $expressionResult = (empty($expressionValue) || $expressionEvaluator->evaluate($expressionValue, ['purchasable' => $purchasable])) && $this->evaluatePurchasableType($purchasable, $modifiers);
         if (true === $expressionResult) {
             $partialElements = $cartLine->getQuantity();
             for ($i = 0; $i < $partialElements; ++$i) {
                 $partialPurchasable = $cartLine->getPurchasable();
                 $moneys[] = $partialPurchasable->getReducedPrice()->getAmount() > 0 ? $partialPurchasable->getReducedPrice() : $partialPurchasable->getPrice();
             }
             $groups = $partialElements / $m;
             if ($groups > 0) {
                 $nbMoneys = $groups * $freePerGroup;
                 $moneysToDiscount = array_slice($moneys, 0, $nbMoneys);
                 foreach ($moneysToDiscount as $moneyToDiscount) {
                     $couponPrice = $couponPrice->add($this->currencyConverter->convertMoney($moneyToDiscount, $currency));
                 }
             }
         }
     }
     return $couponPrice;
 }
Пример #3
0
 /**
  * When a cart goes below 0 (due to discounts), set the amount to 0.
  *
  * @param CartInterface $cart Cart
  */
 public function validateNegativeAmount(CartInterface $cart)
 {
     $amount = $cart->getAmount();
     if ($amount->getAmount() <= 0) {
         $cart->setAmount(Money::create(0, $amount->getCurrency()));
     }
 }
Пример #4
0
 /**
  * Flushes all loaded cart and related entities.
  *
  * We only persist it if have lines loaded inside, so empty carts will never
  * be persisted
  *
  * @param CartInterface $cart Cart
  */
 public function saveCart(CartInterface $cart)
 {
     if (!$cart->getCartLines()->isEmpty()) {
         $this->cartObjectManager->persist($cart);
     }
     $this->cartObjectManager->flush();
 }
 /**
  * A new Order has been created.
  *
  * This method adds Coupon logic in this transformation
  *
  * @param CartInterface  $cart  Cart
  * @param OrderInterface $order Order
  */
 public function createOrderCouponsByCartCoupons(CartInterface $cart, OrderInterface $order)
 {
     $cartCouponAmount = $cart->getCouponAmount();
     if ($cartCouponAmount instanceof MoneyInterface) {
         $order->setCouponAmount($cartCouponAmount);
     }
     /**
      * @var CouponInterface $coupons
      */
     $coupons = $this->cartCouponManager->getCoupons($cart);
     if (empty($coupons)) {
         return;
     }
     /**
      * Before applying Coupons to Order, we should remove old references
      * if exist.
      */
     $this->orderCouponTruncator->truncateOrderCoupons($order);
     /**
      * An event is dispatched for each convertible coupon.
      */
     foreach ($coupons as $coupon) {
         $this->orderCouponEventDispatcher->dispatchOrderCouponOnApplyEvent($order, $coupon);
     }
 }
Пример #6
0
 /**
  * Set Cart in session
  *
  * @param CartInterface $cart Cart
  *
  * @return $this Self object
  */
 public function set(CartInterface $cart)
 {
     if (!$this->saveInSession) {
         return $this;
     }
     $this->session->set($this->sessionFieldName, $cart->getId());
     return $this;
 }
Пример #7
0
 /**
  * Cart view
  *
  * @param FormView      $formView Form view
  * @param CartInterface $cart     Cart
  *
  * @return Response Response
  *
  * @Route(
  *      path = "",
  *      name = "store_cart_view",
  *      methods = {"GET"}
  * )
  *
  * @AnnotationEntity(
  *      class = {
  *          "factory" = "elcodi.wrapper.cart",
  *          "method" = "get",
  *          "static" = false,
  *      },
  *      name = "cart"
  * )
  * @AnnotationForm(
  *      class = "store_cart_form_type_cart",
  *      name  = "formView",
  *      entity = "cart",
  * )
  */
 public function viewAction(FormView $formView, CartInterface $cart)
 {
     $relatedProducts = [];
     if ($cart->getCartLines()->count()) {
         $relatedProducts = $this->get('elcodi_store.provider.product_collection')->getRelatedProducts($cart->getCartLines()->first()->getProduct(), 3);
     }
     $cartCoupons = $this->get('elcodi.manager.cart_coupon')->getCartCoupons($cart);
     return $this->renderTemplate('Pages:cart-view.html.twig', ['cart' => $cart, 'cartCoupons' => $cartCoupons, 'form' => $formView, 'related_products' => $relatedProducts]);
 }
Пример #8
0
 /**
  * Performs all processes to be performed after the order creation.
  *
  * Flushes all loaded order and related entities.
  *
  * @param CartInterface $cart Cart
  */
 public function loadCartShippingAmount(CartInterface $cart)
 {
     $shippingMethodId = $cart->getShippingMethod();
     if (empty($shippingMethodId)) {
         return;
     }
     $shippingMethod = $this->shippingWrapper->getOneById($cart, $shippingMethodId);
     if ($shippingMethod instanceof ShippingMethod) {
         $cart->setShippingAmount($shippingMethod->getPrice());
     }
 }
 /**
  * Validate cart integrity.
  *
  * @param CartInterface $cart Cart
  */
 public function validateCartIntegrity(CartInterface $cart)
 {
     /**
      * Check every CartLine.
      *
      * @var CartLineInterface $cartLine
      */
     foreach ($cart->getCartLines() as $cartLine) {
         $this->validateCartLine($cartLine);
     }
 }
 /**
  * Check if cart meets minimum price requirements for a coupon.
  *
  * @param CartInterface   $cart   Cart
  * @param CouponInterface $coupon Coupon
  *
  * @throws CouponBelowMinimumPurchaseException Minimum value not reached
  */
 public function validateCartCouponMinimumPrice(CartInterface $cart, CouponInterface $coupon)
 {
     $couponMinimumPrice = $coupon->getMinimumPurchase();
     if ($couponMinimumPrice->getAmount() === 0) {
         return;
     }
     $productMoney = $cart->getProductAmount();
     if ($couponMinimumPrice->getCurrency() != $productMoney->getCurrency()) {
         $couponMinimumPrice = $this->currencyConverter->convertMoney($couponMinimumPrice, $productMoney->getCurrency());
     }
     if ($productMoney->isLessThan($couponMinimumPrice)) {
         throw new CouponBelowMinimumPurchaseException();
     }
 }
Пример #11
0
 /**
  * Method subscribed to PreCartLoad event.
  *
  * Iterate over all automatic Coupons and check if they apply.
  * If any applies, it will be added to the Cart
  *
  * @param CartInterface $cart Cart
  */
 public function tryAutomaticCoupons(CartInterface $cart)
 {
     if ($cart->getCartLines()->isEmpty()) {
         return;
     }
     $automaticCoupons = $this->getNonAppliedAutomaticCoupons($cart);
     foreach ($automaticCoupons as $coupon) {
         try {
             $this->cartCouponManager->addCoupon($cart, $coupon);
         } catch (AbstractCouponException $e) {
             // Silently tries next coupon on controlled exception
         }
     }
 }
 /**
  * Calculates and load how many purchasables has this cart.
  *
  * @param CartInterface $cart Cart
  */
 public function loadCartPurchasablesQuantities(CartInterface $cart)
 {
     $quantity = 0;
     /**
      * Calculate max shipping delay.
      */
     foreach ($cart->getCartLines() as $cartLine) {
         /**
          * @var CartLineInterface $cartLine
          */
         $quantity += $cartLine->getQuantity();
     }
     $cart->setQuantity($quantity);
 }
Пример #13
0
 /**
  * test createFromCart method
  *
  * @group order
  */
 public function testCreateOrderFromCart()
 {
     $orderInitialState = $this->getParameter('elcodi.core.cart.order_initial_state');
     $this->assertInstanceOf('Elcodi\\Component\\Cart\\Entity\\Interfaces\\OrderInterface', $this->order);
     $this->assertSame($this->order->getCart(), $this->cart);
     $this->assertTrue($this->cart->isOrdered());
     $this->assertCount(2, $this->order->getOrderLines());
     $this->assertInstanceOf('Elcodi\\Component\\Cart\\Entity\\Interfaces\\OrderHistoryInterface', $this->order->getLastOrderHistory());
     $this->assertEquals($this->order->getLastOrderHistory()->getState(), $orderInitialState);
     $orderHistories = $this->order->getOrderHistories();
     /**
      * @var OrderHistoryInterface $orderHistory
      */
     foreach ($orderHistories as $orderHistory) {
         $this->assertInstanceOf('Elcodi\\Component\\Cart\\Entity\\Interfaces\\OrderHistoryInterface', $orderHistory);
         $this->assertEquals($orderHistory->getState(), $orderInitialState);
     }
     $this->getObjectManager('order')->clear();
     $this->assertCount(1, $this->findAll('order'));
 }
Пример #14
0
 /**
  * Cart view
  *
  * @param FormType      $formType Form type
  * @param CartInterface $cart     Cart
  *
  * @return array
  *
  * @AnnotationEntity(
  *      class = {
  *          "factory" = "elcodi.cart_wrapper",
  *          "method" = "loadCart",
  *          "static" = false,
  *      },
  *      name = "cart"
  * )
  * @AnnotationForm(
  *      class = "store_cart_form_type_cart",
  *      name  = "formView",
  *      entity = "cart",
  * )
  */
 public function viewAction(FormType $formType, CartInterface $cart)
 {
     $relatedProducts = [];
     if ($cart->getCartLines()->count()) {
         $relatedProducts = $this->get('store.product.service.product_collection_provider')->getRelatedProducts($cart->getCartLines()->first()->getProduct(), 3);
     }
     /**
      * Let's sort the cartLines if needed
      */
     $cart->setCartLines($this->get('elcodi.cart_lines_sorter')->sortCartLines($cart->getCartLines()));
     $cartCoupons = $this->get('elcodi.cart_coupon_manager')->getCartCoupons($cart);
     $formView = $this->get('form.factory')->create($formType, $cart)->createView();
     return $this->render('StoreCartBundle:Cart:view.html.twig', ['cart' => $cart, 'cartcoupon' => $cartCoupons, 'form' => $formView, 'related_products' => $relatedProducts]);
 }
Пример #15
0
 /**
  * Get cart coupon objects
  *
  * @param CartInterface $cart Cart
  *
  * @return Collection Coupons
  */
 public function getCoupons(CartInterface $cart)
 {
     /**
      * If Cart id is null means that this cart has been generated from
      * the scratch. This also means that cannot have any Coupon associated.
      * If is this case, we avoid this lookup.
      */
     if ($cart->getId() == null) {
         return new ArrayCollection();
     }
     $cartCoupons = $this->cartCouponRepository->createQueryBuilder('cc')->select(['c', 'cc'])->innerJoin('cc.coupon', 'c')->where('cc.cart = :cart')->setParameter('cart', $cart)->getQuery()->getResult();
     $coupons = array_map(function (CartCouponInterface $cartCoupon) {
         return $cartCoupon->getCoupon();
     }, $cartCoupons);
     return new ArrayCollection($coupons);
 }
Пример #16
0
 /**
  * Add a Purchasable to Cart as a new CartLine
  *
  * This method creates a new CartLine and set item quantity
  * correspondingly.
  *
  * If the Purchasable is already in the Cart, it just increments
  * item quantity by $quantity
  *
  * @param CartInterface        $cart        Cart
  * @param PurchasableInterface $purchasable Product or Variant to add
  * @param integer              $quantity    Number of units to set or increase
  *
  * @return $this self Object
  */
 public function addProduct(CartInterface $cart, PurchasableInterface $purchasable, $quantity)
 {
     /**
      * If quantity is not a number or is 0 or less, product is not added
      * into cart
      */
     if (!is_int($quantity) || $quantity <= 0) {
         return $this;
     }
     foreach ($cart->getCartLines() as $cartLine) {
         /**
          * @var CartLineInterface $cartLine
          */
         if ($cartLine->getPurchasable()->getId() == $purchasable->getId()) {
             /**
              * Product already in the Cart, increase quantity
              */
             return $this->increaseCartLineQuantity($cartLine, $quantity);
         }
     }
     $cartLine = $this->cartLineFactory->create();
     $cartLine->setPurchasable($purchasable)->setQuantity($quantity);
     $this->addLine($cart, $cartLine);
     return $this;
 }
Пример #17
0
 /**
  * Given a cart and a coupon, returns the real value of the coupon.
  * If the type of the coupon is not valid, then an empty Money instance will
  * be returned, with value 0.
  *
  * @param CartInterface   $cart   Abstract Cart object
  * @param CouponInterface $coupon Coupon
  *
  * @return MoneyInterface Coupon price
  */
 public function getCouponAbsolutePrice(CartInterface $cart, CouponInterface $coupon)
 {
     $currency = $this->currencyWrapper->get();
     $couponPrice = Money::create(0, $currency);
     switch ($coupon->getType()) {
         case ElcodiCouponTypes::TYPE_PERCENT:
             $couponPercent = $coupon->getDiscount();
             $couponPrice = $cart->getProductAmount()->multiply($couponPercent / 100);
             break;
         case ElcodiCouponTypes::TYPE_AMOUNT:
             $amount = $coupon->getPrice();
             $couponPrice = $this->currencyConverter->convertMoney($amount, $currency);
             break;
     }
     return $couponPrice;
 }
Пример #18
0
 /**
  * This method calculates all quantities given a Cart
  *
  * @param CartInterface $cart Cart
  *
  * @return CartInterface Cart
  */
 private function calculateCartQuantities(CartInterface $cart)
 {
     $quantity = 0;
     /**
      * Calculate max shipping delay
      */
     foreach ($cart->getCartLines() as $cartLine) {
         /**
          * @var CartLineInterface $cartLine
          */
         $quantity += $cartLine->getQuantity();
     }
     $cart->setQuantity($quantity);
     return $cart;
 }
Пример #19
0
 /**
  * Purchasable related view
  *
  * @param CartInterface $cart Cart
  *
  * @return array
  *
  * @Route(
  *      path = "/related",
  *      name = "store_cart_related",
  *      methods = {"GET"}
  * )
  *
  * @AnnotationEntity(
  *      class = {
  *          "factory" = "elcodi.wrapper.cart",
  *          "method" = "get",
  *          "static" = false,
  *      },
  *      name = "cart"
  * )
  */
 public function relatedAction(CartInterface $cart)
 {
     $purchasables = [];
     $cartLines = $cart->getCartLines();
     /**
      * @var CartLineInterface $cartLine
      */
     foreach ($cartLines as $cartLine) {
         $purchasables[] = $cartLine->getPurchasable();
     }
     $relatedPurchasables = $this->get('elcodi.related_purchasables_provider')->getRelatedPurchasablesFromArray($purchasables, 3);
     return $this->renderTemplate('Modules:_purchasable-related.html.twig', ['purchasables' => $relatedPurchasables]);
 }
Пример #20
0
 /**
  * Remove a Purchasable from Cart.
  *
  * This method removes a Purchasable from the Cart.
  *
  * If the Purchasable is already in the Cart, it just decreases
  * item quantity by $quantity
  *
  * @param CartInterface        $cart        Cart
  * @param PurchasableInterface $purchasable Product or Variant to add
  * @param int                  $quantity    Number of units to set or increase
  *
  * @return $this Self object
  */
 public function removePurchasable(CartInterface $cart, PurchasableInterface $purchasable, $quantity)
 {
     /**
      * If quantity is not a number or is 0 or less, product is not removed
      * from cart.
      */
     if (!is_int($quantity) || $quantity <= 0) {
         return $this;
     }
     foreach ($cart->getCartLines() as $cartLine) {
         /**
          * @var CartLineInterface $cartLine
          */
         if (get_class($cartLine->getPurchasable()) === get_class($purchasable) && $cartLine->getPurchasable()->getId() == $purchasable->getId()) {
             /**
              * Product already in the Cart, decrease quantity.
              */
             return $this->decreaseCartLineQuantity($cartLine, $quantity);
         }
     }
     return $this;
 }
Пример #21
0
 /**
  * Checkout payment step
  *
  * @param CartInterface $cart Cart
  *
  * @return Response Response
  *
  * @Route(
  *      path = "/payment",
  *      name = "store_checkout_payment",
  *      methods = {"GET"}
  * )
  * @EntityAnnotation(
  *      class = {
  *          "factory" = "elcodi.wrapper.cart",
  *          "method" = "get",
  *          "static" = false
  *      },
  *      name = "cart"
  * )
  */
 public function paymentAction(CartInterface $cart)
 {
     /**
      * If some address is missing in loaded cart, then we should go back to
      * address screen
      */
     if (!$cart->getDeliveryAddress() instanceof AddressInterface || !$cart->getBillingAddress() instanceof AddressInterface) {
         return $this->redirect($this->generateUrl('store_checkout_address'));
     }
     /**
      * Available payment methods
      */
     $paymentMethods = $this->get('elcodi.wrapper.payment_methods')->get($cart);
     /**
      * Available shipping methods
      */
     $shippingMethods = $this->get('elcodi.wrapper.shipping_methods')->get($cart);
     /**
      * By default, if the cart has not shipping data and we have available
      * some of them, we assign the first one.
      * Then we reload page to recalculate cart values
      */
     if ($cart->getShippingMethod() == null && !empty($shippingMethods)) {
         $shippingMethodApplied = reset($shippingMethods);
         $cart->setShippingMethod($shippingMethodApplied->getId());
         $this->get('elcodi.object_manager.cart')->flush($cart);
         return $this->redirect($this->generateUrl('store_checkout_payment'));
     }
     $cartCoupons = $this->get('elcodi.manager.cart_coupon')->getCartCoupons($cart);
     return $this->renderTemplate('Pages:checkout-payment.html.twig', ['shippingMethods' => $shippingMethods, 'paymentMethods' => $paymentMethods, 'cart' => $cart, 'cartCoupons' => $cartCoupons]);
 }
Пример #22
0
 /**
  * Given a cart and a coupon, returns the real value of the coupon
  *
  * @param CartInterface   $cart   Abstract Cart object
  * @param CouponInterface $coupon Coupon
  *
  * @return MoneyInterface Coupon price
  */
 protected function getPriceCoupon(CartInterface $cart, CouponInterface $coupon)
 {
     $currency = $this->currencyWrapper->getCurrency();
     switch ($coupon->getType()) {
         case ElcodiCouponTypes::TYPE_AMOUNT:
             $amount = $coupon->getPrice();
             return $this->currencyConverter->convertMoney($amount, $currency);
         case ElcodiCouponTypes::TYPE_PERCENT:
             $couponPercent = $coupon->getDiscount();
             return $cart->getProductAmount()->multiply($couponPercent / 100);
     }
 }
 /**
  * Calculate coupon absolute value.
  *
  * @param CartInterface   $cart   Cart
  * @param CouponInterface $coupon Coupon
  *
  * @return MoneyInterface|false Absolute value for this coupon in this cart.
  */
 public function getCouponAbsoluteValue(CartInterface $cart, CouponInterface $coupon)
 {
     $couponPercent = $coupon->getDiscount();
     return $cart->getPurchasableAmount()->multiply($couponPercent / 100);
 }
 /**
  * Common asserts for a test that empties lines.
  *
  * @param CartLineInterface $line The CartLineInterface needed
  */
 private function assertRemovedLine(CartLineInterface $line)
 {
     $this->assertEmpty($this->cart->getCartLines());
     $this->assertNotNull($this->cart->getId());
     $this->assertEquals(UnitOfWork::STATE_NEW, $this->get('elcodi.object_manager.cart_line')->getUnitOfWork()->getEntityState($line));
 }
Пример #25
0
 /**
  * Get cart coupon objects.
  *
  * @param CartInterface $cart Cart
  *
  * @return CouponInterface[] Coupons
  */
 public function getCoupons(CartInterface $cart)
 {
     /**
      * If Cart id is null means that this cart has been generated from
      * scratch. This also means that it cannot have any Coupon associated.
      * If is this case, we avoid this lookup.
      */
     if ($cart->getId() === null) {
         return [];
     }
     return $this->cartCouponRepository->findCouponsByCart($cart);
 }
 /**
  * Given ShippingRange zones are satisfied by a cart,
  *
  * @param CartInterface          $cart          Cart
  * @param ShippingRangeInterface $shippingRange Carrier Range
  *
  * @return boolean ShippingRange is satisfied by cart
  */
 private function isShippingRangeZonesSatisfiedByCart(CartInterface $cart, ShippingRangeInterface $shippingRange)
 {
     $deliveryAddress = $cart->getDeliveryAddress();
     $shippingRange->getToZone()->getName();
     return $deliveryAddress === null || $this->zoneMatcher->isAddressContainedInZone($deliveryAddress, $shippingRange->getToZone());
 }
Пример #27
0
 /**
  * Check if cart meets basic requirements for a coupon
  *
  * @param CartInterface   $cart   Cart
  * @param CouponInterface $coupon Coupon
  *
  * @throws CouponIncompatibleException Coupon incompatible
  */
 public function validateCoupon(CartInterface $cart, CouponInterface $coupon)
 {
     if ($cart->getTotalItemNumber() === 0) {
         throw new CouponIncompatibleException();
     }
     $this->couponManager->checkCoupon($coupon);
 }
Пример #28
0
 /**
  * Load cart total price.
  *
  * @param CartInterface $cart Cart
  */
 public function loadCartTotalAmount(CartInterface $cart)
 {
     $currency = $this->currencyWrapper->get();
     $finalAmount = clone $cart->getPurchasableAmount();
     /**
      * Calculates the shipping amount.
      */
     $shippingAmount = $cart->getShippingAmount();
     if ($shippingAmount instanceof MoneyInterface) {
         $convertedShippingAmount = $this->currencyConverter->convertMoney($shippingAmount, $currency);
         $finalAmount = $finalAmount->add($convertedShippingAmount);
     }
     /**
      * Calculates the coupon amount.
      */
     $couponAmount = $cart->getCouponAmount();
     if ($couponAmount instanceof MoneyInterface) {
         $convertedCouponAmount = $this->currencyConverter->convertMoney($couponAmount, $currency);
         $finalAmount = $finalAmount->subtract($convertedCouponAmount);
     }
     $cart->setAmount($finalAmount);
 }