Magento 2: При добавлении 10 (или любого количества) товаров в корзину с одинаковым артикулом есть ли способ не увеличивать?
Но вместо этого создайте новые позиции. Например, если это один и тот же товар, просто перечислите его дважды на странице корзины.
Как вы можете видеть на картинке: "Порция Капри-29-Синий" имеет кол-во 2. Но вместо того, чтобы увеличивать его в поле кол-во, просто перечислите каждый из них как отдельный элемент строки.
И по той причине, почему. Вот чего я пытаюсь добиться. используя функции b2b в m2 commerce 2.2.3, я создал способ для ролей покупателей чтобы добавить товары в корзину, а затем сохранить их корзину. когда их корзина будет сохранена, я отправлю их корзину обратно в учетную запись менеджеров. Если у него есть все его покупатели, сохраненные тележки в его аккаунте. покупатель A, покупатель B, покупатель C. допустим, у покупателя A и покупателя C в корзине один и тот же товар. Хорошо, когда я выставляю счета на каждый счет покупателей, как я могу узнать, у каких покупателей был один и тот же продукт, если он просто увеличивается и сливается.
Я надеюсь, что это имеет смысл, и любая помощь будет очень признательна. Благодарю ты.
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;
}
}
Вы можете перечислить все товары с одинаковым артикулом в одной строке, переопределив функцию модели товара с предложением 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;
}
Пожалуйста, обратите внимание, что это будет применитесь к новым товарам, созданным в предложении, а не к старым, которые уже есть в корзине.
Не стесняйтесь задавать любые вопросы, если потребуется.
Один и тот же артикул/товар в корзине может варьироваться в зависимости от опций (например, поддельный пользовательский вариант). Когда товар добавляется в корзину (кнопка "Добавить в корзину"), вам необходимо отправить уникальный параметр для каждого типа клиентов или что-то еще. Не забывайте о полном кэше страниц. Вам нужен некоторый 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->корзина->Добавить продукт ($продукт, $параметры).