Magento2 - Comment ajouter un produit dans le panier par programme lorsque checkout_cart_product_add_after est renvoyé

8

Considérez qu'il y a deux produits, à savoir: le produit A et le produit B. Le produit B est un produit viral que je dois ajouter au panier lorsque le produit A y est ajouté.

Pour ce faire, j'essaie d'ajouter le produit B au panier en observant un événement checkout_cart_product_add_after. Une fois le produit A ajouté, je récupère la quantité de produit ajoutée pour le produit A et en fonction de cela, j'essaie d'ajouter le produit B par programme. Pour ajouter le produit B, j'ai écrit ci-dessous le code:

<?php
namespace MyModule\Applicationcharges\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;

class AddCharges implements ObserverInterface
{
    protected $_productRepository;
    protected $_cart;

    public function __construct(\Magento\Catalog\Model\ProductRepository $productRepository, \Magento\Checkout\Model\Cart $cart){
        $this->_productRepository = $productRepository;
        $this->_cart = $cart;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $item=$observer->getEvent()->getData('quote_item');
        $product=$observer->getEvent()->getData('product');
        $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
        $product->getQty();

        $params = array(
            'product' => 2056,
            'qty' => 1
        );

        $_product = $this->_productRepository->getById(2056);
        $this->_cart->addProduct($_product,$params);
        $this->_cart->save();
    }
}

Cependant, essayer d'ajouter un produit en utilisant $this->_cart->addProduct()ne fonctionne pas. Quelqu'un peut-il s'il vous plaît guider comment cela peut être fait? Y a-t-il quelque chose qui me manque.

Tout conseil sera apprécié.

Dexter
la source

Réponses:

8

Pour tous ceux qui pourraient perdre leur journée à l'avenir, veuillez noter la réponse ci-dessous qui vous sera utile.

Le code ci-dessus pour ajouter un produit au panier fonctionne correctement. Cependant, le problème vient de la logique. Je vais l'expliquer ci-dessous.

Tout d'abord, j'essayais d'ajouter un produit lors d'un événement checkout_cart_product_add_after. Cet événement est déclenché lorsque le produit est ajouté au panier.

En creusant davantage dans le code, si vous devez exécuter la fonction. Le code pour ajouter le produit au panier est:$this->_cart->addProduct($_product,$params);

Si vous archivez la addProductfonction, vendor/module-checkout/Model/Cart.phpvous verrez que c'est la fonction qui distribue l' checkout_cart_product_add_afterévénement.

Par conséquent, dans notre cas, le contrôle retournera à nouveau au fichier d'observateur qui tentera à nouveau d'ajouter le produit au panier. Une récursivité sera créée qui se poursuivra jusqu'à épuisement de la quantité de notre produit.

Une fois la quantité épuisée, elle s'arrêtera. Maintenant, ce que nous devons faire, c'est ajouter une condition pour arrêter cette récursivité. La condition peut être selon votre logique.

Désormais, chaque fois qu'un produit est ajouté au panier $product->getId(), le dernier produit ajouté est renvoyé. Vous pouvez l'utiliser pour mettre la condition.

Au final, mon code ressemble à quelque chose comme ci-dessous:

<?php
namespace MyModule\Applicationcharges\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;

class AddCharges implements ObserverInterface
{
    protected $_productRepository;
    protected $_cart;
    protected $formKey;

    public function __construct(\Magento\Catalog\Model\ProductRepository $productRepository, \Magento\Checkout\Model\Cart $cart, \Magento\Framework\Data\Form\FormKey $formKey){
        $this->_productRepository = $productRepository;
        $this->_cart = $cart;
        $this->formKey = $formKey;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $item = $observer->getEvent()->getData('quote_item');
        $product = $observer->getEvent()->getData('product');
        $item = ($item->getParentItem() ? $item->getParentItem() : $item);

        // Enter the id of the prouduct which are required to be added to avoid recurrssion
        if($product->getId() != 2056){
            $params = array(
                'product' => 2056,
                'qty' => $product->getQty()
            );
            $_product = $this->_productRepository->getById(2056);
            $this->_cart->addProduct($_product,$params);
            $this->_cart->save();
        }

    }
}
Dexter
la source
Et si l'utilisateur met à jour le panier? Pensez-vous que cela se déclenchera toujours?
MagePsycho
2
Même à partir de Magento 2.1.0, cette approche semble obsolète.
MagePsycho
@Dexter comment ajouter un produit avec l'option personnalisée requise au panier?
Shell Suite
@MagePsycho comment je peux savoir ce qui fonctionne car vous suggérez qu'il sera obsolète, je veux dire (j'apprends Magento 2) comment vous le savez. Toute documentation ou toute autre chose qu'un développeur Mage doit lire avant de personnaliser une fonctionnalité.
inrsaurabh
$ item = $ observer-> getEvent () -> getData ('quote_item'); $ product = $ observer-> getEvent () -> getData ('product'); $ item = ($ item-> getParentItem ()? $ item-> getParentItem (): $ item); Si j'imprime echo $ item-> getId (); c'est nul. je ne reçois rien ici.
Dharmesh Hariyani
0

J'ai fait un autre formulaire, pour le client connecté et le panier d'invité

<?php

namespace Ysa\Core\Controller\Api;

use Magento\Framework\App\Action\Action as Action;
use Magento\Framework\App\ResponseInterface;

class Cart extends Action
{
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Magento\Catalog\Model\Product $product,
        \Magento\Quote\Api\CartRepositoryInterface $cartRepositoryInterface,
        \Magento\Store\Model\Store $store,
        \Magento\Checkout\Model\Session $session,
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\Quote\Api\CartManagementInterface $quoteManagement
    ) {
        $this->resultPageFactory        = $resultPageFactory;
        $this->_cartRepositoryInterface = $cartRepositoryInterface;
        $this->_store                   = $store;
        $this->_session                 = $session;
        $this->_productFactory          = $productFactory;
        $this->_quoteManagement         = $quoteManagement;

        parent::__construct($context);
    }

    /**
     * @return ResponseInterface|\Magento\Framework\Controller\ResultInterface|void
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function execute()
    {
        $product_id = $this->getRequest()->getParam('product');
        $product = $this->_productFactory->create();
        $product->load($product_id);

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $customerSession = $objectManager->get('Magento\Customer\Model\Session');

        if ($customerSession->isLoggedIn()) {
            $customer = $customerSession->getCustomer();
            $quoteId = $this->_quoteManagement->createEmptyCartForCustomer($customer->getId());
            $quote = $this->_cartRepositoryInterface->get($quoteId);
            $quote->addProduct($product);
            $this->_cartRepositoryInterface->save($quote);
            $quote->collectTotals();
        } else {
            $quote = $this->_session->getQuote();
            $quote->setStore($this->_store);
            $quote->setCurrency();
            $quote->addProduct($product);
            $quote->save();
            $quote->collectTotals();
            $this->_cartRepositoryInterface->save($quote);
        }
    }
}

Israel Guido
la source