2

I want to programmatically update the quantity of a bundle option of a item in the users cart.

Currently in the cart, a bundle with the option "12 x DIN A4 page".

This is what I have done so far

class ItemInfo [...]

/** @var \Magento\Quote\Model\Quote\Item */
protected $quoteItem;

public function updateNumberOfPages($pages)
{
    $qtyOptions = $this->quoteItem->getQtyOptions();
    assert(count($qtyOptions) == 1);
    $option = reset($qtyOptions);

    $qty = $pages * $this->getNumberOfCopies();
    $this->quoteItem->updateQtyOption($option, $qty);
    $this->quoteItem->save($this);

    $this->quoteItem->getQuote()->setTotalsCollectedFlag(true)->collectTotals();

    return $this;
}

So I call this function updateNumberOfPages(4);

A bit later in the same request, I want to fetch and the new totals:

/** @var \Magento\Quote\Api\CartTotalRepositoryInterface */
protected $cartTotalsRepository;

...

$totals = $this->cartTotalsRepository->get($quoteItem->getQuoteId());

But here, the just updated item still reports "12 x DIN A4 page" - even I have set the qty above to 4.

What is going wrong?

Bonus question: $this->quoteItem->save() is deprecated - what to use instead?

Update I wrote a failing integration test for this:

public function testCanIncreaseNumberOfPages()
{
    $cart =  $this->cartBuilder->withProductRequest("proof", 1, $this->options)
        ->build();
    $quote = $cart->getQuote();
    $quoteItem = $quote->getItemsCollection()->getFirstItem();

    /**
     * @var $itemInfo ItemInfo
     */
    $itemInfo = $this->itemInfoFactory->create(['quoteItem' => $quoteItem]);
    $this->assertEquals(1, $itemInfo->getNumberOfPages());

    $itemInfo->updateNumberOfPages(2);

    $quote = $cart->getQuote();
    $quoteItem = $quote->getItemsCollection()->getFirstItem();
    $itemInfo = $this->itemInfoFactory->create(['quoteItem' => $quoteItem]);
    $this->assertEquals(2, $itemInfo->getNumberOfPages());
}

It fails the second assertion

Failed asserting that '1' matches expected 2.

Upate3

New update function:

public function updateNumberOfPages($pages)
{

    $qty = $pages * $this->getNumberOfCopies();

    $requestInfo = $this->orderOptions['info_buyRequest'];

    $requestInfo[self::OPTION_NAME_PAGES] = $pages;
    $requestInfo[self::OPTION_NAME_QTY] = $qty;

    $buyRequest = new \Magento\Framework\DataObject($requestInfo);
    $this->cart->updateItem($this->quoteItem->getId(), $buyRequest);
    $this->cart->save();

    $this->quoteItem->getQuote()->setTotalsCollectedFlag(false)->collectTotals();

    return $this;
}

New test:

public function testCanIncreaseNumberOfPages()
{
    $cart =  $this->cartBuilder->withProductRequest("proof", 1, $this->options)
        ->build();
    $quote = $cart->getQuote();
    $quoteItem = $quote->getItemsCollection()->getFirstItem();

    $this->assertEquals(6.0, $quote->getGrandTotal());

    /**
     * @var $itemInfo ItemInfo
     */
    $itemInfo = $this->itemInfoFactory->create(['quoteItem' => $quoteItem]);
    $this->assertEquals(1, $itemInfo->getNumberOfPages());

    $itemInfo->updateNumberOfPages(2);

    $quote = $cart->getQuote();
    $quoteItem = $quote->getItemsCollection()->getFirstItem();
    $itemInfo = $this->itemInfoFactory->create(['quoteItem' => $quoteItem]);
    $this->assertEquals(12.0, $quote->getGrandTotal());
    $this->assertEquals(2, $itemInfo->getNumberOfPages());
}

Fails in $this->assertEquals(12.0, $quote->getGrandTotal()); (expects 12, gets 6)

  • Did the quantity change in the DB? Also check if getQuoteId() is the same. – PiTheNumber Jan 29 '18 at 10:35
  • I am not even sure where to search it in the DB .. basically quote_item_option .. but we have buyRequests and options - maybe I have to update the buyRequest (or both) – Alex Jan 29 '18 at 10:47
  • magento.stackexchange.com/a/165201/81 – Alex Jan 29 '18 at 11:08
0

Doing the same that is done in \Magento\Checkout\Controller\Cart\UpdateItemOptions::execute might be the way to got ...

This works in real-life but my integration test still needs fixing:

public function updateNumberOfPages($pages)
{
    $qty = $pages * $this->getNumberOfCopies();

    $requestInfo = $this->orderOptions['info_buyRequest'];
    $requestInfo[self::OPTION_NAME_PAGES][self::OPTION_ID_PROOF_FORMAT ] = $pages;
    $requestInfo[self::OPTION_NAME_QTY][self::OPTION_ID_PROOF_FORMAT] = $qty;

    $buyRequest = new \Magento\Framework\DataObject($requestInfo);

    $item = $this->cart->updateItem($this->quoteItem->getId(), $buyRequest);

    if (is_string($item)) {
        throw new \Magento\Framework\Exception\LocalizedException(__($item));
    }
    if ($item->getHasError()) {
        throw new \Magento\Framework\Exception\LocalizedException(__($item->getMessage()));
    }

    $this->cart->save();

    return $this;
}

to be updated

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.