Jak uzyskać kolekcję produktów z zapasów - w przeciwieństwie do addInStockFilterToCollection ()?

9

Mam obowiązek wyświetlania produktów kategorii na dwóch listach - jednej dla pozycji w magazynie, a drugiej dla pozycji niedostępnych.

używam

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

aby odfiltrować moją kolekcję produktów dla produktów dostępnych w magazynie, ale wydaje się, że nie istnieje równoważna metoda filtrowania produktów niedostępnych w magazynie - przyjrzałem się Mage_CatalogInventory_Model_Stockmodelowi, w którym zdefiniowano wyżej wspomnianą metodę.

Widziałem następujący przykład odzyskiwania brakujących produktów:

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

... ale na pewno nie jest to tylko najlepszy sposób na osiągnięcie tego?

BrynJ
źródło

Odpowiedzi:

3

powiedzmy, że $collectionto twoja kolekcja produktów, którą budujesz w ten sposób:

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

teraz zrób to do swojej kolekcji. To łączy kolekcję z tabelą stanu zapasów.

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

Teraz możesz odfiltrować niedostępne produkty:

$collection->getSelect()->where('stock_status.stock_status = ?', 0);
Marius
źródło
Czy zadziałałoby to bez względu na opcje konfiguracji dla zapasów każdego produktu? (Np. Czy produkt nie jest zarządzany w magazynie lub w magazynie?)
BrynJ
Powinno działać, ponieważ tabela zapasów jest indeksowana i uwzględnia wszystkie możliwe ustawienia. Musisz tylko upewnić się, że indeks akcji jest aktualny
Marius
Dziękuję za potwierdzenie. Wydaje się to być „lekkim” podejściem do uzyskiwania tych danych.
BrynJ,
Użycie tabeli indeksu stanu zapasów zamiast tabeli pozycji magazynowych jest rzeczywiście najlepszym rozwiązaniem.
Fabian Schmengler,
Musiałem wysłać wybór produktu jako pierwszy argument do funkcji Mage :: getModel ('cataloginventory / stock_status') -> addStockStatusToSelect ($ collection-> getSelect (), $ website);
minlare
2

Twój przykład nie uwzględnia wartości „use config”.

Zobaczmy, jak addInStockFilterToCollectiondziała:

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

OK, deleguje na inną metodę:

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

To łączy tabelę zapasów z następującymi warunkami:

  1. Produkt nie korzysta z konfiguracji globalnej ORAZ ma „zarządzaj zapasami” ustawioną na „tak” ORAZ jest w magazynie

    LUB

  2. Produkt nie korzysta z konfiguracji globalnej ORAZ ma opcję „zarządzaj zapasami” ustawioną na „nie”

    LUB

  3. Produkt korzysta z konfiguracji globalnej ORAZ, jeśli konfiguracja globalna to „zarządzaj zapasami = tak”, jest dostępna

Musisz odwrócić warunki w następujący sposób:

  1. Produkt nie korzysta z konfiguracji globalnej ORAZ ma opcję „zarządzaj zapasami” ustawioną na „tak” ORAZ nie ma na magazynie

    LUB

  2. Produkt korzysta z konfiguracji globalnej ORAZ konfiguracja globalna to „zarządzaj zapasem = tak” ORAZ nie ma jej w magazynie

Objaśnienie: Przyjmujesz tylko warunki, w których in_stock jest faktycznie sprawdzany, i zmieniasz porównanie na 0. Warunki, w których in_stock nie jest sprawdzany („zarządzanie zapasem” = „nie”) oznaczają, że produkt jest zawsze w magazynie, niezależnie od stanu zapasów , więc nie uwzględniamy ich w zapytaniu „brak w magazynie”.

To jest twój kod:

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;
}
Fabian Schmengler
źródło
Świetna szczegółowa odpowiedź. Sugerowałbyś więc utworzenie modułu do tego, aby rozszerzyć Mage_CatalogInventory_Model_Stockmodel?
BrynJ
1
Nie przepisuj ani nie przedłużaj. Możesz umieścić tę metodę w dowolnym miejscu, ponieważ nie jest używana $this. Równie dobrze mogłaby to być zwykła funkcja.
Stworzyłbym
1

Poniższy fragment kodu zwróci produkty z kategorii o statusie „Włącz”, „Widoczność”, wyszukiwanie i dostępność towaru „Brak w magazynie”.

$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');
archana bahadur
źródło
0

Możesz tego spróbować.

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

Lub możesz spróbować

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

Nie jestem pewien 100%.

Amit Bera
źródło
Dzięki @AmitBera. Czy możesz podać kontekst swoich odpowiedzi i wyjaśnić różnice?
BrynJ