Magento2 Правильный способ получить товары для заказа

11

Я работаю над расширением платежа M2. Нашему торговцу нужно, чтобы мы отправили детали товара вместе с заказом.

Все работает нормально, но $order->getAllItems();или $order->getAllVisibleItems();возвращает простые и настраиваемые родительские продукты так

если у меня есть 2 продукта в корзине

  • 1 простой продукт
  • 1 Связанный с настраиваемым продуктом

поэтому вместо двух продуктов я получаю три; один простой, связанный продукт и его родительский продукт;

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

    /** @var \Magento\Sales\Model\Order $order */
    $order = $payment->getOrder();
    /**
     * Get All Items of Products
     */
    $productItems = $order->getAllItems() // returning 3 products where I have 2 in cart 
    $productItemsTest = $order->getAllVisibleItems(); // returning 3 products where I have 2 in cart 
Саджид Унар
источник

Ответы:

13

Вот как работают разные методы получения товаров из заказа:

  • getItems(): возвращает массив элементов из загруженной коллекции элементов заказа
  • getAllItems(): возвращает массив всех элементов, которые не помечены как удаленные
  • getAllVisibleItems(): возвращает массив всех элементов, которые не помечены как удаленные и не имеют родительского элемента

Таким образом, чтобы получить только настраиваемый продукт, а не связанный продукт, getAllVisibleItems()это правильный метод:

  • один простой элемент не имеет родителя => видимый
  • настраиваемый элемент не имеет родителя => видимый
  • связанный простой элемент имеет родителя => не виден

Обратите внимание, что, к сожалению, с только getItems()является частью договора на обслуживание вMagento\Sales\Api\Data\OrderInterface

Фабиан Шменглер
источник
Спасибо, но getAllVisibleitems () возвращает простые и конфигурационные продукты вместе, так что не имеет смысла, если следующие изображения могут помочь imgur.com/8ADtnUQ imgur.com/LnMMuOM
Саджид Унар
Изображение выглядит правильно. Или это то, что вы хотите, а не то, что у вас есть?
Фабиан Шменглер
Он должен был вернуть товары из корзины, так что просто два простых продукта, один из конфигурации, а другой как есть; Я сделал эту логику, если ($ productItem-> getProductType () == "simple" && ($ productItem-> getParentItem ())) {continue; } так как простой продукт конфигурации не возвращал цену
Саджид Унар
1
Существует огромная разница между реализацией getAllVisibleItems в Magento 1 и Magento 2. В то время как в M1 дочерние продукты (конфигурируемых, связанных и т. Д.) НЕ отображаются, в M2 они отображаются. Хотя реализация та же самая, $ item-> getParentItemId () вернет ноль в M2 для дочерних элементов. Является ли это ошибкой или нет, ее поведение зависит от используемой версии Magento.
Рикардо Мартинс
3

Лучший способ получить элементы заказа - использовать $order->getAllVisibleItems()

Объясненный выше fschmengler,

getAllItems(): Эта функция возвращает массив всех товаров в корзине с простым конфигурационным продуктом.

Вы получаете три продукта, потому что вы используете, $order->getAllItems() вы должны использовать $order->getAllVisibleItems()метод, чтобы получить оригинальный продукт.

Вы можете проверить больше ссылок из файла vendor/magento/module-quote/Model/Quote.php

/**
     * Retrieve quote items array
     *
     * @return array
     */
    public function getAllItems()
    {
        $items = [];
        foreach ($this->getItemsCollection() as $item) {
            /** @var \Magento\Quote\Model\ResourceModel\Quote\Item $item */
            if (!$item->isDeleted()) {
                $items[] = $item;
            }
        }
        return $items;
    }

    /**
     * Get array of all items what can be display directly
     *
     * @return \Magento\Quote\Model\Quote\Item[]
     */
    public function getAllVisibleItems()
    {
        $items = [];
        foreach ($this->getItemsCollection() as $item) {
            //echo $item->getId()."<br>";
            if (!$item->isDeleted() && !$item->getParentItemId()) {
                $items[] = $item;
            }
        }
        return $items;
    }
Ракеш Джесадия
источник
Спасибо за ответ, но, как я объясняю, он не работает, как ожидалось, см. Следующие изображения в корзине Image imgur.com/8ADtnUQ и отладочное изображение imgur.com/LnMMuOM
Саджид Унар
0

Вы можете использовать цикл Item и исключить дочерний элемент следующим кодом:

/** @var \Magento\Sales\Model\Order $order */
$order = $payment->getOrder();

foreach ($order->getAllItems as $_item) {
     if(!$_item->getData('has_children')) { 
        continue; 
     } else {
        $productIds[]=$_item->getProductId();
     } 
}
Динеш Кумар
источник