예제 #1
0
 function it_should_not_add_violation_if_stock_is_sufficient(PropertyAccessor $propertyAccessor, InventoryUnitInterface $inventoryUnit, StockableInterface $stockable, AvailabilityCheckerInterface $availabilityChecker)
 {
     $propertyAccessor->getValue($inventoryUnit, 'stockable')->willReturn($stockable);
     $propertyAccessor->getValue($inventoryUnit, 'quantity')->willReturn(1);
     $availabilityChecker->isStockSufficient($stockable, 1)->willReturn(true);
     $constraint = new InStock();
     $this->validate($inventoryUnit, $constraint);
 }
 /**
  * @param AddToCartCommandInterface $addCartItemCommand
  *
  * {@inheritDoc}
  */
 public function validate($addCartItemCommand, Constraint $constraint)
 {
     Assert::isInstanceOf($addCartItemCommand, AddToCartCommandInterface::class);
     Assert::isInstanceOf($constraint, CartItemAvailability::class);
     /** @var OrderItemInterface $cartItem */
     $cartItem = $addCartItemCommand->getCartItem();
     $isStockSufficient = $this->availabilityChecker->isStockSufficient($cartItem->getVariant(), $cartItem->getQuantity() + $this->getExistingCartItemQuantityFromCart($addCartItemCommand->getCart(), $cartItem));
     if (!$isStockSufficient) {
         $this->context->addViolation($constraint->message, ['%itemName%' => $cartItem->getVariant()->getInventoryName()]);
     }
 }
예제 #3
0
 /**
  * {@inheritdoc}
  */
 public function decrease($inventoryUnits)
 {
     if (!is_array($inventoryUnits) && !$inventoryUnits instanceof Collection) {
         throw new \InvalidArgumentException('Inventory units value must be array or instance of "Doctrine\\Common\\Collections\\Collection".');
     }
     $quantity = count($inventoryUnits);
     if ($quantity < 1) {
         throw new \InvalidArgumentException('Quantity of units must be greater than 0.');
     }
     if ($inventoryUnits instanceof Collection) {
         $stockable = $inventoryUnits->first()->getStockable();
     } else {
         $stockable = $inventoryUnits[0]->getStockable();
     }
     if (!$this->availabilityChecker->isStockSufficient($stockable, $quantity)) {
         throw new InsufficientStockException($stockable, $quantity);
     }
     $this->eventDispatcher->dispatch(SyliusStockableEvents::PRE_DECREASE, new GenericEvent($stockable));
     $this->backordersHandler->processBackorders($inventoryUnits);
     $onHand = $stockable->getOnHand();
     foreach ($inventoryUnits as $inventoryUnit) {
         if (InventoryUnitInterface::STATE_SOLD === $inventoryUnit->getInventoryState()) {
             --$onHand;
         }
     }
     $stockable->setOnHand($onHand);
     $this->eventDispatcher->dispatch(SyliusStockableEvents::POST_DECREASE, new GenericEvent($stockable));
 }
예제 #4
0
 /**
  * {@inheritdoc}
  */
 public function validate($value, Constraint $constraint)
 {
     /** @var InStock $constraint */
     Assert::isInstanceOf($constraint, InStock::class);
     $stockable = $this->accessor->getValue($value, $constraint->stockablePath);
     if (null === $stockable) {
         return;
     }
     $quantity = $this->accessor->getValue($value, $constraint->quantityPath);
     if (null === $quantity) {
         return;
     }
     if (!$this->availabilityChecker->isStockSufficient($stockable, $quantity)) {
         $this->context->addViolation($constraint->message, ['%stockable%' => $stockable->getInventoryName()]);
     }
 }
예제 #5
0
 /**
  * {@inheritdoc}
  */
 public function resolve(CartItemInterface $item, $data)
 {
     $id = $this->resolveItemIdentifier($data);
     $channel = $this->channelContext->getChannel();
     if (!($product = $this->productRepository->findOneBy(['id' => $id, 'channels' => $channel]))) {
         throw new ItemResolvingException('Requested product was not found.');
     }
     if ($this->restrictedZoneChecker->isRestricted($product)) {
         throw new ItemResolvingException('Selected item is not available in your country.');
     }
     // We use forms to easily set the quantity and pick variant but you can do here whatever is required to create the item.
     $form = $this->formFactory->create('sylius_cart_item', $item, ['product' => $product]);
     $form->submit($data);
     // If our product has no variants, we simply set the master variant of it.
     if (null === $item->getVariant() && !$product->hasVariants()) {
         $item->setVariant($product->getMasterVariant());
     }
     if (null === $item->getVariant() && $product->hasVariants()) {
         throw new ItemResolvingException('Please select variant');
     }
     $variant = $item->getVariant();
     // If all is ok with form, quantity and other stuff, simply return the item.
     if (!$form->isValid() || null === $variant) {
         throw new ItemResolvingException('Submitted form is invalid.');
     }
     $cart = $this->cartProvider->getCart();
     $quantity = $item->getQuantity();
     $context = ['quantity' => $quantity];
     if (null !== ($customer = $cart->getCustomer())) {
         $context['groups'] = $customer->getGroups()->toArray();
     }
     $item->setUnitPrice($this->priceCalculator->calculate($variant, $context));
     foreach ($cart->getItems() as $cartItem) {
         if ($cartItem->equals($item)) {
             $quantity += $cartItem->getQuantity();
             break;
         }
     }
     if (!$this->availabilityChecker->isStockSufficient($variant, $quantity)) {
         throw new ItemResolvingException('Selected item is out of stock.');
     }
     return $item;
 }
예제 #6
0
 /**
  * Check whether stock is sufficient for given
  * stockable and quantity.
  *
  * @param StockableInterface $stockable
  * @param integer            $quantity
  *
  * @return Boolean
  */
 public function isStockSufficient(StockableInterface $stockable, $quantity)
 {
     return $this->checker->isStockSufficient($stockable, $quantity);
 }
예제 #7
0
 function it_delegates_the_stock_sufficiency_checking_to_the_checker(AvailabilityCheckerInterface $checker, StockableInterface $stockable)
 {
     $checker->isStockSufficient($stockable, 3)->shouldBeCalled()->willReturn(false);
     $this->isStockSufficient($stockable, 3)->shouldReturn(false);
 }
 function it_does_not_add_violation_if_total_quantity_of_cart_items_do_not_exceed_available_quantity(ExecutionContextInterface $executionContext, AvailabilityCheckerInterface $availabilityChecker, AddToCartCommandInterface $addCartItemCommand, OrderInterface $order, OrderItemInterface $orderItem, OrderItemInterface $existingOrderItem, ProductVariantInterface $productVariant)
 {
     $addCartItemCommand->getCart()->willReturn($order);
     $addCartItemCommand->getCartItem()->willReturn($orderItem);
     $orderItem->getVariant()->willReturn($productVariant);
     $orderItem->getQuantity()->willReturn(10);
     $existingOrderItem->equals($orderItem)->willReturn(true);
     $order->getItems()->willReturn([$existingOrderItem]);
     $existingOrderItem->getQuantity()->willReturn(10);
     $availabilityChecker->isStockSufficient($productVariant, 20)->willReturn(true);
     $executionContext->addViolation(Argument::any(), Argument::any())->shouldNotBeCalled();
     $cartItemAvailabilityConstraint = new CartItemAvailability();
     $cartItemAvailabilityConstraint->message = 'Insufficient stock';
     $this->validate($addCartItemCommand, $cartItemAvailabilityConstraint);
 }