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?

BrynJ
quelle

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);
Marius
quelle
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;
}
Fabian Schmengler
quelle
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');
Archana Bahadur
quelle
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.

Amit Bera
quelle
Danke @AmitBera. Können Sie bitte einen Kontext für Ihre Antworten angeben und die Unterschiede erläutern?
BrynJ