Как получить коллекцию товаров на складе, в отличие от addInStockFilterToCollection ()?


9

У меня есть требование отображать товары категории в двух списках - один для товаров на складе, другой для товаров на складе.

я использую

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

чтобы отфильтровать мою коллекцию товаров по товарам, имеющимся в наличии, но, по-видимому, не существует эквивалентного метода для фильтрации товаров, которых нет в наличии, - я посмотрел на Mage_CatalogInventory_Model_Stockмодель, в которой определен вышеупомянутый метод.

Я видел следующий пример для извлечения товаров со склада:

$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));

... но, конечно, это не единственный или лучший способ добиться этого?

Ответы:


3

скажем, $collectionэто ваша коллекция продуктов, которую вы создаете так:

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

Теперь сделайте это с вашей коллекцией. Это объединяет коллекцию с таблицей состояния запасов.

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

Теперь вы можете отфильтровать отсутствующие товары:

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

Будет ли это работать независимо от того, какие параметры конфигурации установлены для инвентаря каждого продукта? (Например, продукт, которого нет в наличии на складе или отсутствует на складе?)
BrynJ

Это должно работать, потому что биржевая таблица индексируется и учитывает все возможные настройки. Вам просто нужно убедиться, что ваш фондовый индекс обновлен
Мариус

Спасибо за подтверждение. Это похоже на хороший «легкий» подход к получению этих данных.
BrynJ

Использование таблицы индекса состояния запаса вместо таблицы позиции запаса действительно является лучшим решением.
Фабиан Шменглер

Мне пришлось отправить выбор продукта в качестве первого аргумента в функцию Mage :: getModel ('cataloginventory / stock_status') -> addStockStatusToSelect ($ collection-> getSelect (), $ website);
минлар

2

В вашем примере не учитывается значение «use config».

Давайте посмотрим, как addInStockFilterToCollectionработает:

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

Хорошо, это делегирование другому методу:

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;
}

Это объединяет таблицу инвентаризации со следующими условиями:

  1. Продукт не использует глобальную конфигурацию И имеет «управлять складом», установленным на «да», И есть в наличии

    ИЛИ

  2. Продукт не использует глобальную конфигурацию, и для параметра « Управление запасами» установлено значение «Нет».

    ИЛИ

  3. Продукт использует глобальную конфигурацию И если глобальная конфигурация "управлять запасом = да", есть в наличии

Вы должны инвертировать условия следующим образом:

  1. Продукт не использует глобальную конфигурацию И имеет «управлять складом», установленным на «да», И отсутствует на складе

    ИЛИ

  2. Продукт использует глобальную конфигурацию И глобальная конфигурация "управлять складом = да" И отсутствует на складе

Объяснение: Вы берете только те условия, когда in_stock фактически проверен, и меняете сравнение на 0. Условия, в которых in_stock не проверяется ("manage stock" = "no"), означают, что товар всегда есть в наличии, независимо от состояния запаса. поэтому мы не включаем их в наш запрос "нет в наличии".

Тогда это ваш код:

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;
}

Отличный подробный ответ. Итак, вы бы предложили создать модуль для этого, чтобы расширить Mage_CatalogInventory_Model_Stockмодель?
BrynJ

1
Нет переписать или расширить. Вы можете поместить этот метод в любом месте, поскольку он не использует $this. Это также может быть простой функцией. Я хотел бы создать отдельный модуль и сделать его вспомогательным методом (или, если вам нужно это для другого модуля, добавить его к вспомогательному модулю)
Фабиан Шменглер,

1

Следующий фрагмент кода вернет вам продукты категории, которые имеют статус «Включить», «Видимость», «Каталог», «Поиск» и Наличие на складе «Нет в наличии».

$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

Вы можете попробовать это.

 $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) . ')'
        );

Или вы можете попробовать это

  $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) . ')'
        );

Не уверен 100%.


Спасибо @AmitBera. Не могли бы вы предоставить контекст для ваших ответов и объяснить различия?
BrynJ
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.