¿Cómo obtener la colección de productos de artículos agotados, al contrario de addInStockFilterToCollection ()?


9

Tengo el requisito de mostrar los productos de una categoría en dos listas: una para los artículos en stock y la otra para los artículos agotados.

Estoy usando

Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection()

para filtrar mi colección de productos para los artículos en stock, pero no parece haber un método equivalente para filtrar artículos fuera de stock: he examinado el Mage_CatalogInventory_Model_Stockmodelo, que es donde se define el método mencionado anteriormente.

He visto el siguiente ejemplo para recuperar productos agotados:

$collection->joinField(
                    'is_in_stock',
                    'cataloginventory/stock_item',
                    'is_in_stock',
                    'product_id=entity_id',
                    '{{table}}.stock_id=1',
                    'left'
            )
            ->addAttributeToFilter('is_in_stock', array('eq' => 0));

... pero seguramente esta no es la mejor forma de lograrlo?

Respuestas:


3

Digamos que esa $collectiones su colección de productos que construye así:

$collection = Mage::getModel('catalog/product')->getCollection()
    ->...additional filters here...;

ahora haz esto a tu colección. Esto une la colección con la tabla de estado del stock.

$website = Mage::app()->getWebsite();
Mage::getModel('cataloginventory/stock_status')->addStockStatusToSelect($collection, $website);

Ahora puede filtrar los productos agotados:

$collection->getSelect()->where('stock_status.stock_status = ?', 0);

¿Funcionaría sin importar las opciones de configuración establecidas para el inventario de cada producto? (Por ejemplo, ¿es un producto que no está en stock gestionado en stock o agotado?)
— BrynJ

Debería funcionar, porque la tabla de valores está indexada y tiene en cuenta todas las configuraciones posibles. Solo tiene que asegurarse de que su índice bursátil esté actualizado
— Marius

Gracias por confirmar. Esto parece un buen enfoque "ligero" para obtener estos datos.
— BrynJ

Usar la tabla de índice de estado de existencias en lugar de la tabla de artículos de existencias es, de hecho, la mejor solución.
— Fabian Schmengler

Tuve que enviar el producto seleccionado como primer argumento a la función Mage :: getModel ('cataloginventory / stock_status') -> addStockStatusToSelect ($ colección-> getSelect (), $ sitio web);
— Minlare

2

Su ejemplo no tiene en cuenta el valor de "use config".

Echemos un vistazo a cómo addInStockFilterToCollectionfunciona:

public function addInStockFilterToCollection($collection)
{
    $this->getResource()->setInStockFilterToCollection($collection);
    return $this;
}

OK, está delegando a otro método:

public function setInStockFilterToCollection($collection)
{
    $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
    $cond = array(
        '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=1 AND {{table}}.is_in_stock=1',
        '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=0',
    );

    if ($manageStock) {
        $cond[] = '{{table}}.use_config_manage_stock = 1 AND {{table}}.is_in_stock=1';
    } else {
        $cond[] = '{{table}}.use_config_manage_stock = 1';
    }

    $collection->joinField(
        'inventory_in_stock',
        'cataloginventory/stock_item',
        'is_in_stock',
        'product_id=entity_id',
        '(' . join(') OR (', $cond) . ')'
    );
    return $this;
}

Esto une la tabla de inventario con las siguientes condiciones:

  1. El producto no utiliza la configuración global Y tiene "administrar stock" establecido en "sí" Y está en stock

    O

  2. El producto no utiliza la configuración global Y tiene "administrar stock" establecido en "no"

    O

  3. El producto usa la configuración global Y si la configuración global es "administrar stock = sí", está en stock

Debe invertir las condiciones de la siguiente manera:

  1. El producto no utiliza la configuración global Y tiene "administrar stock" establecido en "sí" Y no está en stock

    O

  2. El producto utiliza la configuración global Y la configuración global es "administrar stock = sí" Y no está en stock

Explicación: Solo toma las condiciones en las que in_stock está realmente verificado y cambia la comparación a 0. Las condiciones en las que in_stock no está marcado ("administrar stock" = "no") significan que el producto siempre está en stock, independientemente del estado del stock , por lo que no los incluimos en nuestra consulta "agotado".

Entonces este es tu código:

public function setOutOfStockFilterToCollection($collection)
{
    $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
    $cond = array(
        '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=1 AND {{table}}.is_in_stock=0'
    );

    if ($manageStock) {
        $cond[] = '{{table}}.use_config_manage_stock = 1 AND {{table}}.is_in_stock=0';
    }

    $collection->joinField(
        'inventory_in_stock',
        'cataloginventory/stock_item',
        'is_in_stock',
        'product_id=entity_id',
        '(' . join(') OR (', $cond) . ')'
    );
    return $this;
}

Gran respuesta detallada. ¿Entonces sugeriría crear un módulo para esto, para extender el Mage_CatalogInventory_Model_Stockmodelo?
— BrynJ

1
No reescribir o extender. Puede colocar este método en cualquier lugar ya que no se usa $this. También podría ser una función simple. Crearía un módulo separado y lo convertiría en un método auxiliar (o si lo necesita para otro módulo, agréguelo al auxiliar de ese módulo)
— Fabian Schmengler

1

El siguiente fragmento de código le devolverá los productos de una categoría que tenga el estado 'Habilitar', Visibilidad 'catálogo, búsqueda' y Stock Disponibilidad 'Agotado'.

$productDetails = Mage::getModel('catalog/category')->load($cat_id)
                  ->getProductCollection()
                  ->addAttributeToSelect('*');

$productDetails->addAttributeToFilter('visibility', 4); 
$productDetails->addAttributeToFilter('status', 1); 
$productDetails->joinField('is_in_stock',
                            'cataloginventory/stock_item',
                            'is_in_stock',
                            'product_id=entity_id',
                            'is_in_stock=0',
                            '{{table}}.stock_id=1',
                            'left');

0

Puedes probar esto.

 $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
        $cond = array(
            '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=1 AND {{table}}.is_in_stock=0',
            '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=0',
        );

        if ($manageStock) {
            $cond[] = '{{table}}.use_config_manage_stock = 1 AND {{table}}.is_in_stock=0';
        } else {
            $cond[] = '{{table}}.use_config_manage_stock = 1';
        }

        $collection->joinField(
            'inventory_in_stock',
            'cataloginventory/stock_item',
            'is_in_stock',
            'product_id=entity_id',
            '(' . join(') OR (', $cond) . ')'
        );

O puedes probar esto

  $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
        $cond = array(
            '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=1 AND {{table}}.is_in_stock=0',
            '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=0',
        );

        if ($manageStock) {
            $cond[] = '{{table}}.is_in_stock=0';


        $collection->joinField(
            'inventory_in_stock',
            'cataloginventory/stock_item',
            'is_in_stock',
            'product_id=entity_id',
            '(' . join(') OR (', $cond) . ')'
        );

No estoy seguro al 100%.


Gracias @AmitBera. ¿Puede proporcionar un contexto para sus respuestas y explicar las diferencias?
— BrynJ
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.