Magento2 - Come aggiungere un prodotto al carrello a livello di codice quando viene attivato checkout_cart_product_add_after


8

Considera che ci sono due prodotti, vale a dire: Prodotto A e Prodotto B. Il prodotto B è un prodotto viruale che devo aggiungere al carrello quando viene aggiunto il prodotto A.

Per fare ciò, sto cercando di aggiungere il prodotto B al carrello osservando un evento checkout_cart_product_add_after. Una volta aggiunto il prodotto A, sto recuperando la quantità di prodotto aggiunto per il prodotto A e sulla base di esso sto provando ad aggiungere il prodotto B a livello di codice. Per aggiungere il prodotto B, ho scritto sotto il codice:

<?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();
    }
}

Tuttavia, provare ad aggiungere un prodotto usando $this->_cart->addProduct()non funziona. Qualcuno può guidare come può essere fatto? C'è qualcosa che mi manca.

Qualsiasi consiglio sarà apprezzato.

Risposte:


8

Per tutti coloro che potrebbero perdere la giornata in futuro, si prega di notare di seguito la risposta che vi sarà utile.

Il codice sopra per aggiungere il prodotto nel carrello funziona bene. Tuttavia, il problema riguarda la logica. Lo spiegherò di seguito.

Prima di tutto stavo cercando di aggiungere un prodotto all'evento checkout_cart_product_add_after. Questo evento viene generato quando il prodotto viene aggiunto al carrello.

Ulteriore ricerca nel codice, se si esegue la funzione. Il codice per aggiungere il prodotto al carrello è:$this->_cart->addProduct($_product,$params);

Se controlli la addProductfunzione in vendor/module-checkout/Model/Cart.php, vedrai che è la funzione che sta inviando l' checkout_cart_product_add_afterevento.

Quindi, nel nostro caso il controllo tornerà di nuovo al file dell'osservatore che tenterà nuovamente di aggiungere il prodotto nel carrello. Verrà creata la ricorsione che durerà fino alla quantità del nostro scarico del prodotto.

Una volta esaurita la quantità, si fermerà. Ora quello che dobbiamo fare è aggiungere una condizione per fermare questa ricorsione. La condizione può essere secondo la tua logica.

Ora ogni volta che un prodotto viene aggiunto al carrello, $product->getId()verrà restituito l'ultimo prodotto aggiunto. Puoi usarlo per mettere condizione.

Alla fine il mio codice è simile al seguente:

<?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();
        }

    }
}

Cosa succede se l'utente aggiorna il carrello? Pensi che questo sarà ancora attivato?
MagoPsycho,

2
Anche da Magento 2.1.0 questo approccio sembra essere deprecato.
MagoPsycho,

@Dexter come aggiungere al carrello l'opzione personalizzata richiesta?
Shell Suite

@MagePsycho come posso sapere quale funzione come stai suggerendo che sarà deprecata, intendo (sto imparando Magento 2) come lo sai. Qualsiasi documentazione o qualsiasi altra cosa che uno sviluppatore di Mage deve leggere prima di personalizzare qualsiasi funzionalità.
Inrsaurabh,

$ item = $ observer-> getEvent () -> getData ('quote_item'); $ product = $ observer-> getEvent () -> getData ('product'); $ item = ($ item-> getParentItem ()? $ item-> getParentItem (): $ item); Se stampo echo $ item-> getId (); è nullo. non sto ottenendo nulla qui.
Dharmesh Hariyani,

0

Ho creato un altro modulo per il cliente registrato e il carrello degli ospiti

<?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);
        }
    }
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.