Wie erhalte ich eine Produktkollektion von nicht vorrätigen Artikeln - im Gegensatz zu addInStockFilterToCollection ()?


9

Ich muss die Produkte einer Kategorie in zwei Listen anzeigen - eine für vorrätige Artikel, die andere für nicht vorrätige Artikel.

Ich benutze

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

Um meine Produktkollektion nach vorrätigen Artikeln zu filtern, scheint es jedoch keine äquivalente Methode zum Filtern nach nicht vorrätigen Artikeln zu geben. Ich habe mir das Mage_CatalogInventory_Model_StockModell angesehen, in dem die oben genannte Methode definiert ist.

Ich habe das folgende Beispiel zum Abrufen von nicht vorrätigen Produkten gesehen:

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

... aber das ist doch nicht nur der beste Weg, dies zu erreichen?

Antworten:


3

Nehmen wir an, das $collectionist Ihre Produktkollektion, die Sie so erstellen:

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

Jetzt mach das mit deiner Sammlung. Dies verbindet die Sammlung mit der Bestandsstatustabelle.

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

Jetzt können Sie die nicht vorrätigen Produkte filtern:

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

Würde dies funktionieren, unabhängig davon, welche Konfigurationsoptionen für das Inventar jedes Produkts festgelegt sind? (ZB ist ein Produkt, das nicht auf Lager oder nicht auf Lager verwaltet wird?)
BrynJ

Es sollte funktionieren, da die Bestandsliste indiziert ist und alle möglichen Einstellungen berücksichtigt. Sie müssen nur sicherstellen, dass Ihr Aktienindex auf dem neuesten Stand ist
Marius

Danke für die Bestätigung. Dies scheint ein guter "leichter" Ansatz zu sein, um diese Daten zu erhalten.
BrynJ

Die Verwendung der Bestandsstatus-Indextabelle anstelle der Bestandsartikel-Tabelle ist in der Tat die beste Lösung.
Fabian Schmengler

Ich musste die Produktauswahl als erstes Argument an die Funktion Mage :: getModel ('cataloginventory / stock_status') senden -> addStockStatusToSelect ($ collection-> getSelect (), $ website);
Minlare

2

In Ihrem Beispiel wird der Wert für "use config" nicht berücksichtigt.

Schauen wir uns an, wie es addInStockFilterToCollectionfunktioniert:

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

OK, es wird an eine andere Methode delegiert:

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

Dies verbindet die Inventartabelle mit den folgenden Bedingungen:

  1. Das Produkt verwendet keine globale Konfiguration UND hat "Lager verwalten" auf "Ja" gesetzt UND ist auf Lager

    ODER

  2. Das Produkt verwendet keine globale Konfiguration UND hat "Lagerverwaltung" auf "Nein" gesetzt.

    ODER

  3. Produkt verwendet globale Konfiguration UND wenn die globale Konfiguration "Lager verwalten = Ja" lautet, ist es auf Lager

Sie müssen die Bedingungen wie folgt umkehren:

  1. Das Produkt verwendet keine globale Konfiguration UND hat "Lager verwalten" auf "Ja" gesetzt UND ist nicht auf Lager

    ODER

  2. Das Produkt verwendet die globale Konfiguration UND die globale Konfiguration lautet "Lager verwalten = Ja" UND ist nicht auf Lager

Erläuterung: Sie nehmen nur die Bedingungen, unter denen der Lagerbestand tatsächlich geprüft wird, und ändern den Vergleich auf 0. Die Bedingungen, unter denen der Lagerbestand nicht geprüft wird ("Lager verwalten" = "nein"), bedeuten, dass das Produkt unabhängig vom Lagerstatus immer auf Lager ist Daher nehmen wir sie nicht in unsere Abfrage "Nicht vorrätig" auf.

Dann ist dies Ihr Code:

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

Tolle detaillierte Antwort. Sie würden also vorschlagen, ein Modul dafür zu erstellen, um das Mage_CatalogInventory_Model_StockModell zu erweitern ?
BrynJ

1
Kein Umschreiben oder Erweitern. Sie können diese Methode an einer beliebigen Stelle platzieren, da sie nicht verwendet wird $this. Es könnte genauso gut eine einfache Funktion sein. Ich würde ein separates Modul erstellen und es zu einer Hilfsmethode machen (oder wenn Sie dies für ein anderes Modul benötigen, fügen Sie es dem Helfer dieses Moduls hinzu)
Fabian Schmengler

1

Das folgende Codefragment gibt Ihnen die Produkte einer Kategorie zurück, die den Status "Aktivieren", "Sichtbarkeit", "Suche" und "Lagerverfügbarkeit" "Nicht vorrätig" haben.

$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

Sie können dies versuchen.

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

Oder Sie können dies versuchen

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

Nicht 100% sicher.


Danke @AmitBera. Können Sie bitte einen Kontext für Ihre Antworten angeben und die Unterschiede erläutern?
BrynJ
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.