Magento2 - Cara menambahkan produk ke troli secara terprogram saat checkout_cart_product_add_after dipecat

8

Pertimbangkan ada dua produk yaitu: Produk A dan Produk B. Produk B adalah produk virual yang perlu saya tambahkan ke troli ketika Produk A ditambahkan ke dalamnya.

Untuk melakukannya, saya mencoba menambahkan Produk B ke troli dengan mengamati suatu peristiwa checkout_cart_product_add_after. Setelah Produk A ditambahkan, saya mengambil jumlah produk yang ditambahkan untuk Produk A dan berdasarkan itu saya mencoba untuk menambahkan Produk B secara terprogram. Untuk menambahkan produk B, saya telah menulis kode di bawah ini:

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

Namun, mencoba menambahkan produk menggunakan $this->_cart->addProduct()tidak berhasil. Adakah yang bisa memandu bagaimana hal ini dapat dilakukan? Apakah ada sesuatu yang saya lewatkan.

Bimbingan apa pun akan dihargai.

Dexter
sumber

Jawaban:

8

Untuk semua yang mungkin menghabiskan hari mereka di masa depan, harap perhatikan jawaban di bawah ini yang akan membantu Anda.

Kode di atas untuk menambahkan produk ke troli berfungsi dengan baik. Namun masalahnya adalah dengan logika. Saya akan jelaskan di bawah ini.

Pertama-tama saya mencoba menambahkan produk di acara checkout_cart_product_add_after. Acara ini dipecat ketika produk ditambahkan ke troli.

Lebih jauh menggali kode, jika Anda menjalankan fungsi. Kode untuk menambahkan produk ke keranjang adalah:$this->_cart->addProduct($_product,$params);

Jika Anda memeriksa addProductfungsi di vendor/module-checkout/Model/Cart.phpAnda akan melihat itu adalah fungsi yang mengirim checkout_cart_product_add_afteracara.

Karenanya, dalam kasus kami kontrol akan kembali ke file pengamat yang lagi-lagi akan mencoba menambahkan produk ke troli. Rekursi akan dibuat yang akan berjalan hingga jumlah produk kami habis.

Setelah kuantitas habis itu akan berhenti. Sekarang yang perlu kita lakukan adalah menambahkan kondisi untuk menghentikan rekursi ini. Syaratnya bisa sesuai logika Anda.

Sekarang setiap kali produk ditambahkan ke troli $product->getId()akan mengembalikan produk terbaru yang ditambahkan. Anda dapat menggunakan ini untuk menempatkan kondisi.

Pada akhirnya kode saya terlihat seperti di bawah ini:

<?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
sumber
Bagaimana jika pengguna memperbarui keranjang? Apakah Anda pikir ini masih akan dipicu?
MagePsycho
2
Bahkan dari Magento 2.1.0 pendekatan ini tampaknya sudah usang.
MagePsycho
@Dexter bagaimana cara menambahkan produk dengan opsi khusus yang diperlukan ke troli?
Shell Suite
@ MagePsycho bagaimana saya bisa tahu bahwa yang berfungsi seperti yang Anda sarankan itu akan ditinggalkan, maksud saya (saya belajar Magento 2) bagaimana Anda tahu itu. Dokumentasi apa pun atau apa pun yang harus dibaca oleh pengembang Mage sebelum kami menyesuaikan fungsionalitas apa pun.
inrsaurabh
$ item = $ observer-> getEvent () -> getData ('quote_item'); $ product = $ observer-> getEvent () -> getData ('product'); $ item = ($ item-> getParentItem ()? $ item-> getParentItem (): $ item); Jika saya mencetak echo $ item-> getId (); itu nol. saya tidak mendapatkan apa-apa di sini.
Dharmesh Hariyani
0

Saya membuat formulir lain, untuk gerobak pelanggan dan tamu

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


Guido Israel
sumber