Як отримати колекцію товарів на складі - навпроти 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);
— minlare

2

Ваш приклад не враховує значення для "config 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 не перевіряється ("керувати запасами" = "ні") означають, що продукт завжди є на складі, незалежно від стану запасу , тому ми не включаємо їх у наш запит "немає в наявності".

Тоді це ваш код:

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. Це також може бути простою функцією. Я створив би окремий модуль і став би його допоміжним методом (або якщо вам це потрібно для іншого модуля, додайте його до помічника цього модуля)
— Fabian Schmengler

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.