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?

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

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

Ś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');

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%.


Dzięki @AmitBera. Czy możesz podać kontekst swoich odpowiedzi i wyjaśnić różnice?
— BrynJ
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.