Magento: добавление простых продуктов из набора в отдельные строки в корзине - PullRequest
6 голосов
/ 29 марта 2012

Мой клиент просит, чтобы каждый простой продукт в комплекте товара, который он продает (Верх одежды и низ), был добавлен в корзину как отдельная позиция, когда пользователь добавляет ее.Может кто-нибудь направить меня в том, как это сделать?Я довольно хорошо разбираюсь в MVC и Zend Framework, но мне нужно немного помочь в поиске точных файлов, которые контролируют добавление связанных продуктов в корзину, или альтернативного метода для добавления этих элементов отдельно.Пожалуйста, предположите, что единственным возможным типом продукта для этой одежды является тип продукта в комплекте.

Ответы [ 3 ]

8 голосов
/ 29 марта 2012

Вам понадобится наблюдатель:

    <checkout_cart_product_add_after>
        <observers>
            <reporting>
                <type>singleton</type>
                <class>Yourcompany_yourmodelname_Model_Observer</class>
                <method>onCartProductAdd</method>
            </reporting>
        </observers>
    </checkout_cart_product_add_after>

Тогда наблюдатель:

class ourcompany_yourmodelname_Model_Observer extends Mage_Core_Model_Abstract
{
    /**
     * Binds to the checkout_cart_product_add_after Event and passes control to the helper function to process the quote
     *
     * @param Varien_Event_Observer $observer
     * @return void
     */
    public function onCartProductAdd($observer){
        $product = $observer->getProduct();
        $isProductBundle = ($product->getTypeId() == 'bundle');
        $items_to_add = array();
        $oTypeInstance = $oProduct->getTypeInstance(true);
        $aSelections = $oTypeInstance->getSelectionsCollection($aOptionIds, $product );
        $aOptions = $oTypeInstance->getOptionsByIds($aOptionIds, $product);
        $bundleOptions = $aOptions->appendSelections($aSelections, true);
        foreach ($bundleOptions as $bundleOption) {
            if ($bundleOption->getSelections()) {
                $bundleSelections = $bundleOption->getSelections();    
                foreach ($bundleSelections as $bundleSelection) {
                       $items_to_add[] = $bundleSelection.getID();

               }

            }
       }
       insertExtractedProducts($items_to_add);
    }

     /**
     * Add extracted products into quote
     *
     * @param array $items_to_add
      */
    public function insertExtractedProducts($items_to_add){
        /**@var $cart Mage_Checkout_Model_Cart**/
        $cart = Mage::helper('checkout/cart')->getCart();
        $ids_to_add = array();
        foreach($items_to_add as $item_to_be_added){
            $ids_to_add[] = $item_to_be_added->getProductId();
        }
        $cart->addProductsByIDs($ids_to_add);
        $cart->save();
        Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
        }
   }

Простой пример, но он может помочь.

Связанные продукты могут быть сложными для понимания при работе с ним через код: Вот пример изображения: enter image description here

У каждого продукта в комплекте есть один ко многим параметрам, которые в конце будут ссылками на продукты, которые будут добавлены в пакет в Корзине.

Каждый вариант состоит из одного-многих вариантов, которые будут связаны между собой продуктами, которые окажутся в корзине покупок в рамках этого продукта. Один выбор, как правило, может быть установлен по умолчанию и уже будет выбран на странице продукта. По этой ссылке можно найти больше информации о том, как создавать и настраивать связанные продукты, потому что в этом документе мы обсудим только его программную часть. Страница отображения продукта в комплекте будет выглядеть следующим образом: enter image description here

Это может выглядеть следующим образом в корзине после нажатия «Добавить в корзину»: Образец комплекта

Sample Shampoo
1 x Moisturiser-125ml $29.95
Default Conditioner
1 x Moisturiser-60g $99.95

При опросе этого продукта с помощью кода вы загружаете его, как любой обычный продукт:

$oProduct->load($vProductId);

После загрузки необходимо получить экземпляр типа продукта, чтобы можно было загрузить параметры для этого типа продукта.

$oTypeInstance = $oProduct->getTypeInstance(true);

Теперь мы можем получить список идентификаторов опций для этого продукта следующим образом:

$oTypeInstance = $oProduct->getTypeInstance(true);

Для опроса Выборов мы добавим список опций в коллекцию, затем получим коллекцию Опций, а также их соответствующие Выборы:

$aSelections = $oTypeInstance->getSelectionsCollection($aOptionIds, $oProduct );
$aOptions = $oTypeInstance->getOptionsByIds($aOptionIds, $oProduct);
$bundleOptions = $aOptions->appendSelections($aSelections, true);

Теперь у нас есть коллекция опций, и у каждой опции будет коллекция опций. Теперь мы можем просмотреть варианты и посмотреть их выбор.

foreach ($bundleOptions as $bundleOption) {
            if ($bundleOption->getSelections()) {
                $bundleSelections = $bundleOption->getSelections();

                foreach ($bundleSelections as $bundleSelection) {
                     // get some data here
                     $vName = $bundleOption->getTitle();
               }

            }
}

Чтобы получить список необходимых продуктов для выбора комплектного продукта, вы можете использовать следующий код:

$requiredChildren = $this->getChildrenIds($product->getId(),$required=true);

Затем вы можете просмотреть массив идентификаторов и загрузить продукты по их идентификаторам, чтобы получить больше информации об этих продуктах.

Связанные продукты в корзине

Чтобы просмотреть выбранные параметры связанного продукта на карточке покупок, вы можете использовать что-то вроде этого:

/**
 * @var Mage_Bundle_Model_Product_Type
 */
$typeInstance = $this->getProduct()->getTypeInstance(true);

// get bundle options
$optionsQuoteItemOption =  $this->getItem()->getOptionByCode('bundle_option_ids');
$bundleOptionsIds = unserialize($optionsQuoteItemOption->getValue());
if ($bundleOptionsIds) {
    /**
    * @var Mage_Bundle_Model_Mysql4_Option_Collection
    */
    $optionsCollection = $typeInstance->getOptionsByIds($bundleOptionsIds, $this->getProduct());

    // get and add bundle selections collection
    $selectionsQuoteItemOption = $this->getItem()->getOptionByCode('bundle_selection_ids');

    $selectionsCollection = $typeInstance->getSelectionsByIds(
        unserialize($selectionsQuoteItemOption->getValue()),
        $this->getProduct()
    );

    $bundleOptions = $optionsCollection->appendSelections($selectionsCollection, true);
    foreach ($bundleOptions as $bundleOption) {
        if ($bundleOption->getSelections()) {
            $label = $bundleOption->getTitle()

            $bundleSelections = $bundleOption->getSelections();

            foreach ($bundleSelections as $bundleSelection) {                        
                    $sName = $bundleSelection->getName();
            }
            // some more code here to do stuff
        }
    }
}

Этот код получает параметры из связанного продукта элемента цитаты, а затем получает параметры для этого продукта в коллекции, а затем находит «выбранный» вариант выбора.

НТН, Shaun

1 голос
/ 25 января 2019

Вот как это можно сделать в Magento 2.3 с помощью плагина вокруг (перехватчика) для метода Magento \ Checkout \ Model \ Cart-> addProduct ().

Метод addProduct () вызывается, когда покупатель добавляет товар в корзину. Добавив код для этого метода через плагин, вы можете изменить способ добавления продукта в корзину.

  1. Определите плагин в Vendor / Module / etc / frontend / di.xml:
<?xml version="1.0"?>
<!--
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="\Magento\Checkout\Model\Cart">
        <plugin name="add-bundle-products-separate" type="Vendor\Module\Plugin\Checkout\Model\CartPlugin" sortOrder="1"/>
    </type>
</config>

Это то, что говорит Magento, что для этого конкретного метода существует плагин.

Ссылка: https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html

  1. Создать класс плагина. Вендор / Модуль / Плагин / Оформить заказ / Модель / CartPlugin.php:
<?php
namespace Vendor\Module\Plugin\Checkout\Model;

use \Magento\Catalog\Model\Product;
use \Magento\Framework\DataObject;
use \Magento\Checkout\Model\Cart;

/**
 * Class CartPlugin
 *
 * @package Ppwd\CrossSell\Plugin\Checkout\Model
 *
 */
class CartPlugin {

    /**
     * @param Cart $subject
     * @param \Closure $proceed
     * @param Product $productInfo
     * @param DataObject|int|array $requestInfo
     * @return Cart $subject
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     */
    public function aroundAddProduct(
        $subject,
        $proceed,
        $productInfo,
        $requestInfo = null
    ) {
        // Detect if we are adding a bundle product to cart
        if (!is_numeric($productInfo) && $productInfo->getTypeId() == 'bundle') {

            $buyRequest = new DataObject($requestInfo);

            // List of products selected as part of the bundle
            $cartCandidates = $productInfo->getTypeInstance()->prepareForCartAdvanced($buyRequest, $productInfo);
            $productIds = [];

            // Add each item in bundle as if it were separately added to cart
            /** @var Product $cartCandidate */
            foreach ($cartCandidates as $cartCandidate) {
                if ($cartCandidate->getTypeId() != 'bundle') {
                    for ($i = 0; $i < $cartCandidate->getCartQty(); $i++) {
                        $productIds[] = $cartCandidate->getId();
                    }
                }
            }
            $subject->addProductsByIds($productIds);
            return $subject;
        }

        // Return original result from addProduct() as if plugin didn't exist
        $result = $proceed($productInfo, $requestInfo);
        return $result;
    }
}

Когда вы закончите, если вы добавите пакет в корзину, позиции будут отображаться отдельно, а не сгруппированы вместе, как обычно есть в комплекте.

1 голос
/ 12 февраля 2015

Я сделал это, чтобы решить запрос клиента на добавление содержимого пакета как отдельных элементов в корзину. Просто замените

$cart->addProduct($product, $params) 

с

if ($product->getTypeId() == 'bundle') {
    $request = new Varien_Object($params);
    $cartCandidates = $product->getTypeInstance(true)->prepareForCartAdvanced($request, $product, Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_FULL);
    $idstoadd = array();
    foreach ($cartCandidates as $cartCandidate) {
        if ($cartCandidate->getTypeId() == 'simple') {
            for ($i = 0; $i < $cartCandidate->getCartQty(); $i++) {
                $idstoadd[] = $cartCandidate->getId();
            }
        }
    }
    $cart->addProductsByIds($idstoadd);
} else {
    $cart->addProduct($product, $params);
}

в файле cartController .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...