Comment obtenir la collection de produits en rupture de stock - à l'opposé de addInStockFilterToCollection ()?

9

J'ai l'obligation d'afficher les produits d'une catégorie dans deux listes - une pour les articles en stock, l'autre pour les articles en rupture de stock.

j'utilise

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

pour filtrer ma collection de produits pour les articles en stock, mais il ne semble pas y avoir de méthode équivalente pour filtrer les articles en rupture de stock - j'ai regardé le Mage_CatalogInventory_Model_Stockmodèle, où la méthode susmentionnée est définie.

J'ai vu l'exemple suivant pour récupérer des produits en rupture de 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));

... mais ce n'est sûrement pas seulement le meilleur moyen d'y parvenir?

BrynJ
la source

Réponses:

3

disons que $collectionc'est votre collection de produits que vous créez comme ceci:

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

maintenant faites cela à votre collection. Cela rejoint la collection avec la table d'état des stocks.

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

Vous pouvez maintenant filtrer les produits en rupture de stock:

$collection->getSelect()->where('stock_status.stock_status = ?', 0);
Marius
la source
Est-ce que cela fonctionnerait quelles que soient les options de configuration définies pour l'inventaire de chaque produit? (Par exemple, un produit qui n'est pas géré en stock ou en rupture de stock?)
BrynJ
Cela devrait fonctionner, car la table de stock est indexée et elle prend en compte tous les paramètres possibles. Il vous suffit de vous assurer que votre indice boursier est à jour
Marius
Merci d'avoir confirmé. Cela semble être une belle approche "légère" pour obtenir ces données.
BrynJ
Utiliser la table d'index de l'état des stocks au lieu de la table des articles en stock est en effet la meilleure solution.
Fabian Schmengler
J'ai dû envoyer le produit select comme premier argument à la fonction Mage :: getModel ('cataloginventory / stock_status') -> addStockStatusToSelect ($ collection-> getSelect (), $ website);
minlare
2

Votre exemple ne prend pas en compte la valeur "use config".

Voyons comment cela addInStockFilterToCollectionfonctionne:

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

OK, il délègue à une autre méthode:

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

Cela rejoint la table d'inventaire avec les conditions suivantes:

  1. Le produit n'utilise pas la configuration globale ET a "gérer le stock" réglé sur "oui" ET est en stock

    OU

  2. Le produit n'utilise pas la configuration globale ET a "gérer le stock" défini sur "non"

    OU

  3. Le produit utilise la configuration globale ET si la configuration globale est "gérer le stock = oui", est en stock

Vous devez inverser les conditions comme suit:

  1. Le produit n'utilise pas la configuration globale ET a "gérer le stock" défini sur "oui" ET n'est pas en stock

    OU

  2. Le produit utilise la configuration globale ET la configuration globale est "gérer le stock = oui" ET n'est pas en stock

Explication: Vous prenez uniquement les conditions dans lesquelles in_stock est réellement vérifié et changez la comparaison à 0. Les conditions dans lesquelles in_stock n'est pas vérifiée ("gérer le stock" = "non") signifient que le produit est toujours en stock, quel que soit l'état du stock , nous ne les incluons donc pas dans notre requête "rupture de stock".

Alors voici votre 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
la source
Grande réponse détaillée. Vous proposeriez donc de créer un module pour cela, pour étendre le Mage_CatalogInventory_Model_Stockmodèle?
BrynJ
1
Pas de réécriture ni d'extension. Vous pouvez mettre cette méthode n'importe où car elle ne l'utilise pas $this. Cela pourrait tout aussi bien être une fonction simple. Je créerais un module séparé et en ferais une méthode d'assistance (ou si vous en avez besoin pour un autre module, l'ajoutez à l'aide de ce module)
Fabian Schmengler
1

L'extrait de code suivant vous renverra les produits d'une catégorie dont le statut est «Activer», Visibilité «catalogue, recherche» et Disponibilité en stock «Rupture de stock».

$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
la source
0

Vous pouvez essayer ça.

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

Ou vous pouvez essayer ceci

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

Pas sûr à 100%.

Amit Bera
la source
Merci @AmitBera. Pouvez-vous fournir un contexte pour vos réponses et expliquer les différences?
BrynJ