Magento 2: При добавлении 10 (или любого количества) товаров в корзину с одинаковым артикулом есть ли способ не увеличивать?


Но вместо этого создайте новые позиции. Например, если это один и тот же товар, просто перечислите его дважды на странице корзины.

enter image description here

Как вы можете видеть на картинке: "Порция Капри-29-Синий" имеет кол-во 2. Но вместо того, чтобы увеличивать его в поле кол-во, просто перечислите каждый из них как отдельный элемент строки.

И по той причине, почему. Вот чего я пытаюсь добиться. используя функции b2b в m2 commerce 2.2.3, я создал способ для ролей покупателей чтобы добавить товары в корзину, а затем сохранить их корзину. когда их корзина будет сохранена, я отправлю их корзину обратно в учетную запись менеджеров. Если у него есть все его покупатели, сохраненные тележки в его аккаунте. покупатель A, покупатель B, покупатель C. допустим, у покупателя A и покупателя C в корзине один и тот же товар. Хорошо, когда я выставляю счета на каждый счет покупателей, как я могу узнать, у каких покупателей был один и тот же продукт, если он просто увеличивается и сливается.

Я надеюсь, что это имеет смысл, и любая помощь будет очень признательна. Благодарю ты.

Author: Vivek Kumar, 2018-07-12

3 answers

Если каждый раз хотите добавлять отдельный товар в корзину, то вы можете подключить метод representProduct, расположенный в Magento\Quote\Model\Quote\Item

Ваш [Vendor]/[Module]/etc/di.xml выглядит так, как показано ниже

<?xml version='1.0'?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd" >
    <type name='Magento\Quote\Model\Quote\Item'>
        <plugin name='beforeDispatch' type='[Vendor]\[Module]\Plugin\Model\Quote\ItemPlugin' sortOrder='99'/>
    </type>    
</config>

И ваш [Vendor]\[Module]\Plugin\Model\Quote\ItemPlugin.php выглядит так, как показано ниже

<?php

namespace [Vendor]\[Module]\Plugin\Model\Quote;
class ItemPlugin 
{
    
    public function afterRepresentProduct(\Magento\Quote\Model\Quote\Item $subject, $result)
    {
        if ($yourCondition) { // if there is no condition return always false
             $result = false;
        }
        return $result;
    }
}
 9
Author: Murtuza Zabuawala, 2020-09-02 03:28:29

Вы можете перечислить все товары с одинаковым артикулом в одной строке, переопределив функцию модели товара с предложением representProduct(), которая определяет, как товар будет представлен в корзине во время создания самого товара с предложением.

Просто добавьте предпочтение Magento\Quote\Model\Quote\Item в свой di.xml следующим образом;

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Quote\Model\Quote\Item" type="Vendor\Module\Model\Quote\Quote\Item" />   
</config>

И в вашем Vendor\Module\Model\Quote\Quote\Item добавьте следующий код;

<?php
namespace Vendor\Module\Model\Quote\Quote;

use Magento\Framework\Api\AttributeValueFactory;
use Magento\Framework\Api\ExtensionAttributesFactory;
use Magento\Quote\Api\Data\CartItemInterface;

/**
 * Sales Quote Item Model
 *
 * @method \Magento\Quote\Model\ResourceModel\Quote\Item _getResource()
 * @method \Magento\Quote\Model\ResourceModel\Quote\Item getResource()
 * @method string getCreatedAt()
 * @method \Magento\Quote\Model\Quote\Item setCreatedAt(string $value)
 * @method string getUpdatedAt()
 * @method \Magento\Quote\Model\Quote\Item setUpdatedAt(string $value)
 * @method int getStoreId()
 * @method \Magento\Quote\Model\Quote\Item setStoreId(int $value)
 * @method int getParentItemId()
 * @method \Magento\Quote\Model\Quote\Item setParentItemId(int $value)
 * @method int getIsVirtual()
 * @method \Magento\Quote\Model\Quote\Item setIsVirtual(int $value)
 * @method string getDescription()
 * @method \Magento\Quote\Model\Quote\Item setDescription(string $value)
 * @method string getAdditionalData()
 * @method \Magento\Quote\Model\Quote\Item setAdditionalData(string $value)
 * @method int getFreeShipping()
 * @method \Magento\Quote\Model\Quote\Item setFreeShipping(int $value)
 * @method int getIsQtyDecimal()
 * @method \Magento\Quote\Model\Quote\Item setIsQtyDecimal(int $value)
 * @method int getNoDiscount()
 * @method \Magento\Quote\Model\Quote\Item setNoDiscount(int $value)
 * @method float getWeight()
 * @method \Magento\Quote\Model\Quote\Item setWeight(float $value)
 * @method float getBasePrice()
 * @method \Magento\Quote\Model\Quote\Item setBasePrice(float $value)
 * @method float getCustomPrice()
 * @method float getTaxPercent()
 * @method \Magento\Quote\Model\Quote\Item setTaxPercent(float $value)
 * @method \Magento\Quote\Model\Quote\Item setTaxAmount(float $value)
 * @method \Magento\Quote\Model\Quote\Item setBaseTaxAmount(float $value)
 * @method \Magento\Quote\Model\Quote\Item setRowTotal(float $value)
 * @method \Magento\Quote\Model\Quote\Item setBaseRowTotal(float $value)
 * @method float getRowTotalWithDiscount()
 * @method \Magento\Quote\Model\Quote\Item setRowTotalWithDiscount(float $value)
 * @method float getRowWeight()
 * @method \Magento\Quote\Model\Quote\Item setRowWeight(float $value)
 * @method float getBaseTaxBeforeDiscount()
 * @method \Magento\Quote\Model\Quote\Item setBaseTaxBeforeDiscount(float $value)
 * @method float getTaxBeforeDiscount()
 * @method \Magento\Quote\Model\Quote\Item setTaxBeforeDiscount(float $value)
 * @method float getOriginalCustomPrice()
 * @method \Magento\Quote\Model\Quote\Item setOriginalCustomPrice(float $value)
 * @method string getRedirectUrl()
 * @method \Magento\Quote\Model\Quote\Item setRedirectUrl(string $value)
 * @method float getBaseCost()
 * @method \Magento\Quote\Model\Quote\Item setBaseCost(float $value)
 * @method \Magento\Quote\Model\Quote\Item setPriceInclTax(float $value)
 * @method float getBasePriceInclTax()
 * @method \Magento\Quote\Model\Quote\Item setBasePriceInclTax(float $value)
 * @method \Magento\Quote\Model\Quote\Item setRowTotalInclTax(float $value)
 * @method float getBaseRowTotalInclTax()
 * @method \Magento\Quote\Model\Quote\Item setBaseRowTotalInclTax(float $value)
 * @method int getGiftMessageId()
 * @method \Magento\Quote\Model\Quote\Item setGiftMessageId(int $value)
 * @method string getWeeeTaxApplied()
 * @method \Magento\Quote\Model\Quote\Item setWeeeTaxApplied(string $value)
 * @method float getWeeeTaxAppliedAmount()
 * @method \Magento\Quote\Model\Quote\Item setWeeeTaxAppliedAmount(float $value)
 * @method float getWeeeTaxAppliedRowAmount()
 * @method \Magento\Quote\Model\Quote\Item setWeeeTaxAppliedRowAmount(float $value)
 * @method float getBaseWeeeTaxAppliedAmount()
 * @method \Magento\Quote\Model\Quote\Item setBaseWeeeTaxAppliedAmount(float $value)
 * @method float getBaseWeeeTaxAppliedRowAmnt()
 * @method \Magento\Quote\Model\Quote\Item setBaseWeeeTaxAppliedRowAmnt(float $value)
 * @method float getWeeeTaxDisposition()
 * @method \Magento\Quote\Model\Quote\Item setWeeeTaxDisposition(float $value)
 * @method float getWeeeTaxRowDisposition()
 * @method \Magento\Quote\Model\Quote\Item setWeeeTaxRowDisposition(float $value)
 * @method float getBaseWeeeTaxDisposition()
 * @method \Magento\Quote\Model\Quote\Item setBaseWeeeTaxDisposition(float $value)
 * @method float getBaseWeeeTaxRowDisposition()
 * @method \Magento\Quote\Model\Quote\Item setBaseWeeeTaxRowDisposition(float $value)
 * @method float getDiscountTaxCompensationAmount()
 * @method \Magento\Quote\Model\Quote\Item setDiscountTaxCompensationAmount(float $value)
 * @method float getBaseDiscountTaxCompensationAmount()
 * @method \Magento\Quote\Model\Quote\Item setBaseDiscountTaxCompensationAmount(float $value)
 * @method null|bool getHasConfigurationUnavailableError()
 * @method \Magento\Quote\Model\Quote\Item setHasConfigurationUnavailableError(bool $value)
 * @method \Magento\Quote\Model\Quote\Item unsHasConfigurationUnavailableError()
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @SuppressWarnings(PHPMD.ExcessivePublicCount)
 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
 */
class Item extends \Magento\Quote\Model\Quote\Item
{
    /**
     * Prefix of model events names
     *
     * @var string
     */
    protected $_eventPrefix = 'sales_quote_item';

    /**
     * Parameter name in event
     *
     * In observe method you can use $observer->getEvent()->getObject() in this case
     *
     * @var string
     */
    protected $_eventObject = 'item';

    /**
     * Quote model object
     *
     * @var \Magento\Quote\Model\Quote
     */
    protected $_quote;

    /**
     * Item options array
     *
     * @var array
     */
    protected $_options = [];

    /**
     * Item options by code cache
     *
     * @var array
     */
    protected $_optionsByCode = [];

    /**
     * Not Represent options
     *
     * @var array
     */
    protected $_notRepresentOptions = ['info_buyRequest'];

    /**
     * Flag stating that options were successfully saved
     *
     */
    protected $_flagOptionsSaved;

    /**
     * Array of errors associated with this quote item
     *
     * @var \Magento\Sales\Model\Status\ListStatus
     */
    protected $_errorInfos;

    /**
     * @var \Magento\Framework\Locale\FormatInterface
     */
    protected $_localeFormat;

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

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

    /**
     * @var \Magento\CatalogInventory\Api\StockRegistryInterface
     */
    protected $stockRegistry;

    protected $scopeConfig;

    /**
     * @param \Magento\Framework\Model\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param ExtensionAttributesFactory $extensionFactory
     * @param AttributeValueFactory $customAttributeFactory
     * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
     * @param \Magento\Sales\Model\Status\ListFactory $statusListFactory
     * @param \Magento\Framework\Locale\FormatInterface $localeFormat
     * @param Item\OptionFactory $itemOptionFactory
     * @param Item\Compare $quoteItemCompare
     * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
     * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
     * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
     * @param array $data
     *
     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
     */
    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        ExtensionAttributesFactory $extensionFactory,
        AttributeValueFactory $customAttributeFactory,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
        \Magento\Sales\Model\Status\ListFactory $statusListFactory,
        \Magento\Framework\Locale\FormatInterface $localeFormat,
        \Magento\Quote\Model\Quote\Item\OptionFactory $itemOptionFactory,
        \Magento\Quote\Model\Quote\Item\Compare $quoteItemCompare,
        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        $this->scopeConfig = $scopeConfig;
        // $this->registry = $registry;
        // $this->extensionFactory = $extensionFactory;
        // $this->customAttributeFactory = $customAttributeFactory;
        // $this->productRepository = $productRepository;
        // $this->priceCurrency = $priceCurrency;
        $this->_errorInfos = $statusListFactory->create();
        $this->_localeFormat = $localeFormat;
        $this->_itemOptionFactory = $itemOptionFactory;
        $this->quoteItemCompare = $quoteItemCompare;
        $this->stockRegistry = $stockRegistry;
        $this->resource = $resource;
        $this->resourceCollection = $resourceCollection;
        parent::__construct(
            $context,
            $registry,
            $extensionFactory,
            $customAttributeFactory,
            $productRepository,
            $priceCurrency,
            $statusListFactory,
            $localeFormat,
            $itemOptionFactory,
            $quoteItemCompare,
            $stockRegistry,
            $resource,
            $resourceCollection,
            $data
        );
    }

    public function representProduct($product)
    {
        $itemProduct = $this->getProduct();

        if (!$product || $itemProduct->getId() == $product->getId()) {
            return true;
        }

        if (!$product || $itemProduct->getId() != $product->getId()) {
            return false;
        }

        /**
         * Check maybe product is planned to be a child of some quote item - in this case we limit search
         * only within same parent item
         */
        $stickWithinParent = $product->getStickWithinParent();
        if ($stickWithinParent) {
            if ($this->getParentItem() !== $stickWithinParent) {
                return false;
            }
        }

        // Check options
        $itemOptions = $this->getOptionsByCode();
        $productOptions = $product->getCustomOptions();

        if (!$this->compareOptions($itemOptions, $productOptions)) {
            return false;
        }
        if (!$this->compareOptions($productOptions, $itemOptions)) {
            return false;
        }
    }
}

Для объяснения я только что добавил следующее условие в функцию representProduct()

if (!$product || $itemProduct->getId() == $product->getId()) {
            return true;
        }

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

Не стесняйтесь задавать любые вопросы, если потребуется.

 4
Author: Vivek Kumar, 2018-07-25 01:08:29

Один и тот же артикул/товар в корзине может варьироваться в зависимости от опций (например, поддельный пользовательский вариант). Когда товар добавляется в корзину (кнопка "Добавить в корзину"), вам необходимо отправить уникальный параметр для каждого типа клиентов или что-то еще. Не забывайте о полном кэше страниц. Вам нужен некоторый JavaScript, который изменит полезную нагрузку кнопок "Добавить в корзину" для каждого типа товара. Реализация JS зависит от вас (с использованием sections.xml или переопределение существующих компонентов Magento 2 JS или виджетов Jquery_Ui, ..).

См.: \Magento\Checkout\Model\Cart::addProduct($productInfo, $requestInfo = null) Если $RequestInfo является массивом, то там будет ваш параметр.

$requestInfo = [
..
'lorem' => 'ipsum'
..
];

Кроме того, Magento знает, как связать ("представить") продукт с помощью комбинации sku и $RequestInfo.

См.: \Magento\Quote\Model\Quote\Item::representProduct($product) и \Magento\Quote\Model\Quote::getItemByProduct

/**
 * Retrieve quote item by product id
 *
 * @param   \Magento\Catalog\Model\Product $product
 * @return  \Magento\Quote\Model\Quote\Item|bool
 */
public function getItemByProduct($product)
{
    foreach ($this->getAllItems() as $item) {
        if ($item->representProduct($product)) {
            return $item;
        }
    }
    return false;
}

Не думайте о параметре функции $product как о продукте, извлеченном из каталога. $product - это представление модели продукта каталога в "контексте" корзины. Он содержит предварительно настроенные параметры продукта, добавленного в корзину с помощью "Добавить кнопка "В корзину" через класс действий: \Magento\Оформить заказ\Контроллер\Корзина\Добавить::выполнить();

..
$params = $this->getRequest()->getParams();
..
$this->cart->addProduct($product, $params);
..
$this->cart->save();
..

Вы - новый параметр, который однозначно идентифицирует что-то, что может очень хорошо вписываться в $params. Для целей отладки введите $params в действие добавить в корзину. Чем добавлять товары различных типов в корзину. Это будет более понятно для обратного проектирования.

Это не имеет отношения к вашим вопросам. Если вы попытаетесь добавить один и тот же товар в корзину несколько раз с помощью одного и того же сценария (действия) в одном запрос/вызов, вам придется полностью загружать модель продукта каждый раз, когда вы вызываете $cart->addProduct(). Как вы знаете, выбранные параметры продукта для корзины устанавливаются внутри объекта $product во время $this->корзина->Добавить продукт ($продукт, $параметры).

 1
Author: Daniel Ifrim, 2018-07-23 09:07:15