Sylius通过CartItemController添加到购物车总共0,00

We are currently developing an ERP-based webshop with Sylius. One of the features is that a customer can select multiple sizes and quantities and add them to their cart in one action.

Normally Sylius would work with a request-based ItemResolver for only one variant. We've tried to override the CartItemController so that we would be able to loop the request variables and add all the items to the cart.

We tried to use this code:

    try {
        // When we have multiple
        $reqSize      = $request->request->get('size');
        $reqQuantity  = $request->request->get('quantity');
        $reqProductID = $request->request->get('product_id');
        $reqColorID   = $request->request->get('variant_color_id');

        if (null !== $reqSize && null !== $reqQuantity && null !== $reqProductID && null !== $reqColorID && count($reqSize) === count($reqQuantity)) {
            $provider            = $this->get('sylius.cart_provider'); // Implements the CartProviderInterface.
            $currentCart         = $provider->getCart();
            $priceCalculator     = $this->get('sylius.price_calculator');
            $availabilityChecker = $this->get('sylius.availability_checker');

            $productRepo = $this->get('sylius.repository.product');
            $variantRepo = $this->get('sylius.repository.product_variant');
            $sizeRepo    = $this->get('jartazi.repository.sizegrid_size');
            $colorRepo   = $this->get('jartazi.repository.color');

            $product = $productRepo->find(intval($reqProductID));
            $color   = $colorRepo->find(intval($reqColorID));

            for ($i = 0; $i < count($reqSize); $i++) {
                $size     = $sizeRepo->find(intval($reqSize[$i]));
                $variant  = $variantRepo->findOneBy(['object' => $product, 'size' => $size, 'color' => $color]);
                $quantity = intval($reqQuantity[$i]);

                if (null === $variant) {
                    throw new ItemResolvingException('Selected item is out of stock.');
                }


                if (null !== $product && null !== $color && null !== $size && null !== $variant) {
                    // Make a cart item
                    $item = $this->get('sylius.factory.cart_item')->createNew();

                    $item->setSize($size);
                    $item->setVariant($variant);
                    $item->setQuantity($quantity);

                    $context = ['quantity' => $quantity];

                    if (null !== $customer = $cart->getCustomer()) {
                        $context['groups'] = $customer->getGroups()->toArray();
                    }

                    $item->setUnitPrice($priceCalculator->calculate($variant, $context));

                    // Check for equal products
                    foreach ($currentCart->getItems() as $cartItem) {
                        if ($cartItem->equals($item)) {
                            $quantity += $cartItem->getQuantity();
                            break;
                        }
                    }

                    if (!$availabilityChecker->isStockSufficient($variant, $quantity)) {
                        throw new ItemResolvingException('Selected item is out of stock.');
                    }

                    $event = new CartItemEvent($cart, $item);

                    // Update models
                    $eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_INITIALIZE, $event);
                    $eventDispatcher->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($cart));
                    $eventDispatcher->dispatch(SyliusCartEvents::CART_SAVE_INITIALIZE, $event);

                    // Write flash message
                    $eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_COMPLETED, new FlashEvent());
                }
            }

            return $this->redirectAfterAdd($configuration);
        }
    } catch (ItemResolvingException $exception) {
        // Write flash message
        $eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_ERROR, new FlashEvent($exception->getMessage()));

        return $this->redirectAfterAdd($configuration);
    }

But when we add one to the cart, the cart total stays 0,00

Are we missing something in order to have the correct totals when adding a CartItem without an ItemResolver?

Thanks in advance.

As specified by Coudenysj you probably need to call the OrderItemQuantityModifier somewhere in your code.

I think you need to manually call the modifier before you set the quantity

$this->get('sylius.order_item_quantity_modifier')->modify($item, $quantity);

// $item->setQuantity($quantity); 

Actually it appears you just need to call the modify function and it updates the quantity to the correct value

I had a lot of trouble making my own add to cart code for this reason. I ended up modifying the CartItemType. But now i do need to be able to add multiple to the cart at once. So i would be very interested to hear if this solves your issues.

Please post an update

Yes, with use of this service we were able to correctly modify the quantity and the unit prices. Thanks, we clearly overlooked this service. Our modification of the CartItem ($item->setQuantity($quantity);) we also deleted as this was a custom method, the setter was normally not available.