Magento2 Forma correcta de obtener artículos de pedido

10

Estoy trabajando en M2 Payment Extension, nuestro comerciante necesita que enviemos los detalles de los artículos junto con el pedido.

Todo funciona bien pero $order->getAllItems();o $order->getAllVisibleItems();devuelve productos principales simples y configurables, por lo que

si tengo 2 productos en el carrito

  • 1 producto simple
  • 1 Asociado de producto configurable

así que en lugar de obtener dos productos, obtengo tres; un producto simple asociado y su producto principal;

Puedo intentar extraer los productos correctos, pero estoy seguro de que debe ser otro

    /** @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 
Sajid Unar
fuente

Respuestas:

12

Así es como funcionan los diferentes métodos para obtener artículos de un pedido:

  • getItems(): devuelve una matriz de artículos de la colección de artículos de pedido cargados
  • getAllItems(): devuelve una matriz de todos los elementos que no están marcados como eliminados
  • getAllVisibleItems(): devuelve una matriz de todos los elementos que no están marcados como eliminados y no tienen un elemento primario

Entonces, para obtener solo el producto configurable y no su producto asociado, getAllVisibleItems()es el método correcto:

  • el elemento simple no tiene un padre => visible
  • el elemento configurable no tiene un padre => visible
  • el elemento simple asociado tiene un padre => no visible

Tenga en cuenta que desafortunadamente, a partir de solo getItems()forma parte del contrato de servicio enMagento\Sales\Api\Data\OrderInterface

Fabian Schmengler
fuente
Gracias, hombre, pero getAllVisibleitems () devuelve productos simples y de configuración juntos, por lo que no tiene sentido si las siguientes imágenes pueden ayudar imgur.com/8ADtnUQ imgur.com/LnMMuOM
Sajid Unar
La imagen se ve correcta. ¿O es esto lo que quieres, no lo que tienes?
Fabian Schmengler
Debería haber devuelto los artículos del carrito, así que solo dos productos simples, uno de config y otro tal como están; Hice esta lógica si ($ productItem-> getProductType () == "simple" && ($ productItem-> getParentItem ())) {continuar; } ya que el producto simple de configuración no devolvía el precio
Sajid Unar
1
Hay una gran diferencia entre la implementación de getAllVisibleItems en Magento 1 y Magento 2. Mientras que en M1 los productos secundarios (configurables, agrupados, etc.) NO se muestran, en M2 sí lo están. Aunque la implementación es la misma, $ item-> getParentItemId () devolverá nulo en M2 para los elementos secundarios. Ya sea que se trate de un error o no, su comportamiento varía de acuerdo con la versión de Magento que está utilizando.
Ricardo Martins
2

La mejor manera de obtener artículos de pedido es usando $order->getAllVisibleItems()

Explicado por fschmengler arriba,

getAllItems(): Esta función devuelve una matriz de todos los artículos del carrito con un producto simple de configuración también.

Usted obtiene tres productos porque tiene uso $order->getAllItems() , tiene que usar el $order->getAllVisibleItems()método para obtener el producto original.

Puedes consultar más referencias del archivo 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;
    }
Rakesh Jesadiya
fuente
Gracias por responder, pero como explico no funciona como se esperaba, vea las siguientes imágenes en el carrito Imagen imgur.com/8ADtnUQ y la imagen de depuración imgur.com/LnMMuOM
Sajid Unar
0

puede usar el bucle de elemento y excluir el elemento secundario con el siguiente código:

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

foreach ($order->getAllItems as $_item) {
     if(!$_item->getData('has_children')) { 
        continue; 
     } else {
        $productIds[]=$_item->getProductId();
     } 
}
Dinesh Kumar
fuente