Skip to content

Commit

Permalink
feature #701 Availability product variant (alexander-schranz, mamazu)
Browse files Browse the repository at this point in the history
This PR was merged into the 1.0-dev branch.

Discussion
----------

Replaces #648

Commits
-------

2d5157f Add availibility check for product
236dbed Adding availablity checker in a non bc-breaking way
72e19d5 Fixing the tests
db1e5d7 Reverting back useless changes
  • Loading branch information
lchrusciel authored Feb 23, 2021
2 parents 45b02bf + db1e5d7 commit 1e105c6
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
26 changes: 26 additions & 0 deletions spec/Modifier/OrderModifierSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Inventory\Checker\AvailabilityCheckerInterface;
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
use Sylius\Component\Order\Processor\OrderProcessorInterface;
use Sylius\ShopApiPlugin\Modifier\OrderModifierInterface;
Expand Down Expand Up @@ -76,4 +77,29 @@ function it_creates_new_cart_item_and_add_it_to_order_with_proper_variant_and_qu

$this->modify($order, $productVariant, 4);
}

function it_throws_an_exception_if_the_product_is_out_of_stock(
CartItemFactoryInterface $cartItemFactory,
OrderItemQuantityModifierInterface $orderItemQuantityModifier,
OrderProcessorInterface $orderProcessor,
ObjectManager $orderManager,
OrderInterface $order,
OrderItemInterface $cartItem,
ProductVariantInterface $productVariant,
AvailabilityCheckerInterface $availabilityChecker
): void {
$this->beConstructedWith($cartItemFactory, $orderItemQuantityModifier, $orderProcessor, $orderManager, $availabilityChecker);

$order->getItems()->willReturn(new ArrayCollection([]));

$cartItemFactory->createForCart($order)->willReturn($cartItem);

$availabilityChecker->isStockSufficient($productVariant, 4)->shouldBeCalled()->willReturn(false);
$orderProcessor->process(Argument::cetera())->shouldNotBeCalled();

$orderManager->persist(Argument::cetera())->shouldNotBeCalled();

$this->shouldThrow(\InvalidArgumentException::class)
->during('modify', [$order, $productVariant, 4]);
}
}
30 changes: 28 additions & 2 deletions src/Modifier/OrderModifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Inventory\Checker\AvailabilityCheckerInterface;
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
use Sylius\Component\Order\Processor\OrderProcessorInterface;
use Webmozart\Assert\Assert;

final class OrderModifier implements OrderModifierInterface
{
Expand All @@ -26,28 +28,41 @@ final class OrderModifier implements OrderModifierInterface
/** @var ObjectManager */
private $orderManager;

/** @var AvailabilityCheckerInterface|null */
private $availabilityChecker;

public function __construct(
CartItemFactoryInterface $cartItemFactory,
OrderItemQuantityModifierInterface $orderItemQuantityModifier,
OrderProcessorInterface $orderProcessor,
ObjectManager $orderManager
ObjectManager $orderManager,
?AvailabilityCheckerInterface $availabilityChecker = null
) {
$this->cartItemFactory = $cartItemFactory;
$this->orderItemQuantityModifier = $orderItemQuantityModifier;
$this->orderProcessor = $orderProcessor;
$this->orderManager = $orderManager;
$this->availabilityChecker = $availabilityChecker;

if ($this->availabilityChecker === null) {
@trigger_error(sprintf('Not passing a $availabilityChecker to %s constructor is deprecated', self::class), \E_USER_DEPRECATED);
}
}

public function modify(OrderInterface $order, ProductVariantInterface $productVariant, int $quantity): void
{
$cartItem = $this->getCartItemToModify($order, $productVariant);
if (null !== $cartItem) {
$this->orderItemQuantityModifier->modify($cartItem, $cartItem->getQuantity() + $quantity);
$targetQuantity = $cartItem->getQuantity() + $quantity;
$this->checkCartQuantity($productVariant, $targetQuantity);

$this->orderItemQuantityModifier->modify($cartItem, $targetQuantity);
$this->orderProcessor->process($order);

return;
}

$this->checkCartQuantity($productVariant, $quantity);
$cartItem = $this->cartItemFactory->createForCart($order);
$cartItem->setVariant($productVariant);
$this->orderItemQuantityModifier->modify($cartItem, $quantity);
Expand All @@ -70,4 +85,15 @@ private function getCartItemToModify(OrderInterface $cart, ProductVariantInterfa

return null;
}

private function checkCartQuantity(ProductVariantInterface $productVariant, int $targetQuantity): void
{
if($this->availabilityChecker === null) {
return;
}
Assert::true(
$this->availabilityChecker->isStockSufficient($productVariant, $targetQuantity),
'Not enough stock for product variant: '. $productVariant->getCode()
);
}
}

0 comments on commit 1e105c6

Please sign in to comment.