Kategorieseite erstellen, auf der alle Sonderpreisprodukte angezeigt werden

12

Grundsätzlich habe ich eine Kategorie "Produkte zum Verkauf" erstellt, in der ich automatisch alle Produkte in meinem Katalog aufnehmen möchte , auf die ein Sonderpreis angewendet wurde (über Katalog> Produkte verwalten). Ich möchte, dass die Seite die geschichteten Navigations- und Sortierfunktionen beibehält, die eine Standard-Magento-Kategorieseite enthält.

Es scheint, dass dies für die Mehrheit der Magento-Benutzer von Wert ist, und ich bin überrascht, dass es nicht Teil der Kernfunktionalität ist.

Ich habe über ein Dutzend Stack Exchange-Antworten, -Blog-Posts und -Foren ausprobiert, und bisher hat nichts funktioniert. Hat jemand eine programmatische Lösung dafür?

=== EDIT ===

Basierend auf der Kritik von @ pspahn in den Kommentaren unten habe ich mich für eine alternative Methode entschieden, um ähnliche Funktionen zu erzielen. Wenn Sie an dieser Linie interessiert sind, beschreibt @ sander-mangel eine Methode, die durchaus machbar erscheint.

rokkor
quelle
Es scheint mir, dass die Anforderung "automatisch alle Sonderpreisprodukte enthalten" etwas übertrieben ist. Ich gehe davon aus, dass das Endergebnis darin besteht, dass Sie eine Seite mit Sonderpreisen möchten und dass sie wie eine Kategorieseite aussieht. Anscheinend könnten Sie stattdessen einfach Ihr eigenes Modell / Ihre eigene Sammlung (basierend auf Produkten mit einem Sonderpreis) erstellen und diese Sammlung in Vorlagen basierend auf den Kategorieansichtsseiten verwenden. Ich sehe eine Kategorie, die automatisch ausgefüllt wird, einfach nicht als eine gute Lösung. Wie können Sie beispielsweise verhindern, dass ein Benutzer sie ändert?
pspahn
@pspahn Danke für deine Antwort. Ich verstehe Ihre Kritik und stimme Ihrer Argumentation zu. Ich könnte die von Sander Mangel beschriebene Methode mit einem zusätzlichen "category_save_after" -Betrachter verwenden, aber das scheint übertrieben. Ich werde mit einer alternativen Lösung fortfahren.
rokkor
@pspahn - Ich verstehe nicht, was Sie mit "Wie können Sie verhindern, dass ein Benutzer Änderungen vornimmt" meinen. Können Sie das näher erläutern?
ProxiBlue
@ProxiBlue Wenn Sie eine Kategorie erstellen und automatisch mit Produkten füllen, kann ein Administrator im Backend einfach in diese Kategorie wechseln und Produkte manuell hinzufügen / entfernen.
pspahn
@pspahn ok, mit user habe ich als frontend user falsch verstanden.
ProxiBlue

Antworten:

8

Am einfachsten ist es, eine benutzerdefinierte Erweiterung zu erstellen, die mit einem Observer und einem Cronjob zusammenarbeitet.

Erstellen Sie eine Kategorie für die Verkaufsprodukte. Auf diese Weise können Sie die normalen Magento-Funktionen im Frontend wie Layered Navigation usw. verwenden.

Um die Produkte dieser Kategorie automatisch zu erhalten, verwenden wir den Observer und den Cronjob. Der Beobachter beobachtet das catalog_product_save_afterEreignis, das ausgelöst wird, wenn ein Produkt im Backend gespeichert wird. In diesem Fall können Sie Datum und Datum überprüfen special_price, um festzustellen, ob Sie das Produkt in die Verkaufskategorie aufnehmen oder von dort entfernen müssen.special_price_fromspecial_date_to

Der Cronjob ist für das Besondere von und zu Terminen da. Leeren Sie jede Nacht nach Mitternacht zuerst die Verkaufskategorie aller Produkte. Verwenden Sie dann eine Sammlung, um alle Produkte abzurufen, die einen Sonderpreis haben und unter das Sonderangebot von und nach Datum fallen. Wenn ja, verschieben Sie sie in diese Verkaufskategorie.

Sander Mangel
quelle
7

Die von @SanderMangel angebotene Lösung ist erstklassig. Ich kann dazu beitragen, dies mit einem Code zu erweitern, den ich derzeit in meinem Modul Automated / Dynamic Category-Produkte verwende - das die Möglichkeit bietet, Kategorieregeln für bestimmte Produkte zu erstellen

Der Code passt eine Standardproduktkollektion an, um alle Produkte mit einem Sonderpreis zu erhalten, der an dem Tag festgelegt wird, an dem der Code ausgeführt wird. Sie können dies im Cron verwenden, um die Kategorien um 00:00 Uhr neu aufzufüllen und sicherzustellen, dass sie auf dem neuesten Stand sind.

Beachten Sie, dass der Code aus einem größeren Modul extrahiert wird. Daher habe ich die relevanten Teile hier für Sie komprimiert. Es kann eine oder zwei Variablen geben, die in diesem Auszug nicht enthalten sind, aber sie lassen sich leicht ableiten, oder fragen Sie einfach :)

Das $ category-Objekt ist die tatsächliche Kategorie, die die Produkte enthalten soll. Mit dem folgenden Code können Sie den Rabatt auch in% angeben :)

$collection = $category->getProductCollection();

$todayDate = Mage::app()->getLocale()->date()->toString(Varien_Date::DATE_INTERNAL_FORMAT);
$collection->addAttributeToFilter(array(
    array(
        'attribute' => "special_to_date",
        'null' => true
    ),
    array(
        'attribute' => "special_to_date",
        'from' => $todayDate,
        //'to'      => $todayDate,
        'date' => true
    )
));
$collection->addAttributeToFilter(array(
    array(
        'attribute' => "special_from_date",
        'null' => true
    ),
    array(
        'attribute' => "special_from_date",
        //'from'    => $todayDate,
        'to' => $todayDate,
        'date' => true
    )
));

$collection->addAttributeToSelect('special_price','left');
$collection->addAttributeToSelect('price','left');
$select = $collection->getSelect();

if (strpos($value, '%') > 0) {
    $value = str_replace('%', '', $value);
    $select->where('( 100 - (( at_special_price.value * 100 ) / at_price.value ) )  ' . $operator . ' ' . $value);
} else {
    $select->where('((at_price.value - at_special_price.value)) ' . $operator . ' ' . $value);
}

Nun ist zu beachten, dass die Sammlung keine Produkte zurückgibt, da sie Links zu den normalen Katalog- <-> Produktlink-Tabellen enthält. Da Sie nicht an den aktuell verknüpften Produkten interessiert sind, müssen Sie diese Tabellenbeziehung aus der Sammlung löschen.

Ich benutze den folgenden Code, um das zu erledigen:

/**
 * Remove Catalog Product Link elements from collection
 * 
 * @param type $collection
 * @return type
 */
public function removeCatProPart($collection)
{
    $select = $collection->getSelect();
    $fromPart = $select->getPart(Zend_Db_Select::FROM);
    $select->reset(Zend_Db_Select::FROM);

    if (array_key_exists('cat_pro', $fromPart)) {
        unset($fromPart['cat_pro']);
        // also remove any reference to the table in the rest of the query
        $columns = $select->getPart(Zend_Db_Select::COLUMNS);
        $columnRemoved = false;
        foreach ($columns as $columnKey => $column) {
            if ($column[0] == 'cat_pro') {
                unset($columns[$columnKey]);
                $columnRemoved = true;
            }
        }

        if ($columnRemoved) {
            $select->setPart(Zend_Db_Select::COLUMNS, $columns);
        }

        $orderPart = $select->getPart(Zend_Db_Select::ORDER);
        $orderRemoved = false;
        foreach ($orderPart as $orderKey => $order) {
            if ($order[0] == 'cat_pro') {
                unset($orderPart[$orderKey]);
                $orderRemoved = true;
            }
        }

        if ($orderRemoved) {
            $select->setPart(Zend_Db_Select::ORDER, $orderPart);
        }
    }
    $select->setPart(Zend_Db_Select::FROM, $fromPart);
    return $collection;
}

Als zusätzlichen Bonus können Sie dieselbe Methode zum Anpassen der Katalogproduktsammlung verwenden und Produkte suchen, die sich aufgrund von Katalogregeln im Spezialmodus befinden:

$storeDate = Mage::app()->getLocale()->storeTimeStamp($this->getStoreId());
$value = $this->getValue();
$conditions = 'price_rule.product_id = e.entity_id AND ';
$conditions .= "(from_time = 0
    OR from_time <= " . $storeDate . ")
    AND (to_time = 0
    OR to_time >= " . $storeDate . ") AND ";
$conditions .= "price_rule.rule_id IN (" . $value . ")";
$collection->getSelect()->joinInner(
        array('price_rule' => $collection->getTable('catalogrule/rule_product')), $conditions);
$collection->setFlag('applied_catalog_rule_id', true);
$collection->setFlag('applied_rule', true);

Sobald Sie die funktionierende Sammlung haben, müssen Sie nur noch alle IDs aus der Sammlung abrufen, das Array umdrehen und verwenden $category->setPostedProducts($products); und ein $ category-> save () l; um das Update abzuschließen.

Der Vollständigkeit halber ist hier mein täglicher Cron, der die dynamischen Kategorien auf dem neuesten Stand hält. (Wiederum bezieht es sich auf Methoden, die hier nicht enthalten sind, aber ich bin sicher, dass Sie damit in die richtige Richtung gelangen

Habe Spaß :)

public static function rebuildAllDynamic($schedule)
{
    try {
        $tempDir = sys_get_temp_dir() . "/";
        $fp = fopen($tempDir . "dyncatprod_rebuild.lock", "w+");
        if (flock($fp, LOCK_EX | LOCK_NB)) {
            if (Mage::getStoreConfig('dyncatprod/debug/enabled')) {
                   mage::log("DynCatProd - rebuildAllDynamic");
            }
            if (!Mage::getStoreConfig('dyncatprod/rebuild/max_exec')) {
                ini_set('max_execution_time', 3600); // 1 hour
            }
            $categories = Mage::getModel('catalog/category')
                ->getCollection()
                ->addAttributeToSelect('*')
                ->addIsActiveFilter()
                ->addAttributeToFilter('dynamic_attributes', array('notnull' => true));

            foreach ($categories as $category) {
                $products = Mage::helper('dyncatprod')->getDynamicProductIds($category);
                if (is_array($products)) {
                    if (Mage::getStoreConfig('dyncatprod/debug/enabled')) {
                        mage::log("rebuilding :" . $category->getName() . ' ' . $category->getPath() );
                    }
                    $products = array_flip($products);
                    $category->setPostedProducts($products);
                    $category->setIsDynamic(true);
                    $category->save();
                }
            }
            flock($fp, LOCK_UN); 
            unlink($tempDir . "dyncatprod_rebuild.lock");
        } else {
            mage::log('Could not execute cron for rebuildAllDynamic -file lock is in place, job may be running');
        }
    } catch (Exception $e) {
        flock($fp, LOCK_UN); 
        unlink($tempDir . "dyncatprod_rebuild.lock");
        mage::logException($e);
        return $e->getMessage();
    }
}

ref: http://www.proxiblue.com.au/magento-dynamic-category-products.html

ProxiBlue
quelle
5

Hier ist die Sammlung, die Ihnen die Ergebnisse aller Sonderpreisprodukte in Ihrem Katalog geben soll, die Sie auf einer Seite anzeigen können

$collection = Mage::getResourceModel('catalog/product_collection')
    ->addAttributeToSelect('price')
    ->setStoreId($this->getStoreId());

$date = strtotime(date('Y-m-d')); $current_date = date("Y-m-d hh:mm:ss",$date);

$collection = $collection
    ->addAttributeToFilter('price',
        array('gt'=>0))
    ->addAttributeToFilter('visibility',
        array('neq'=>Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE));

if (Mage::getStoreConfigFlag(Mage_Catalog_Helper_Product_Flat::XML_PATH_USE_PRODUCT_FLAT, $this->getStoreId())){
    $collection = $collection->addAttributeToFilter('special_price',array('lt'=>new Zend_Db_Expr('e.price')));
}
else{
    $collection = $collection->addAttributeToFilter(array(
        array('attribute'=>'special_price','lt'=>new Zend_Db_Expr('at_price.value'))
    ));
}

$collection = $collection->addAttributeToFilter(array(
        array('attribute'=>'special_from_date','lteq'=>$current_date),
        array('attribute'=>'special_from_date','eq'=>''),
        array('attribute'=>'special_from_date','null'=>true)
    ),'','left')
    ->addAttributeToFilter(array(
        array('attribute'=>'special_to_date','gteq'=>$current_date),
        array('attribute'=>'special_to_date','eq'=>''),
        array('attribute'=>'special_to_date','null'=>true)
            ),'','left');

$collection->getSelect()->group('e.entity_id');

return $collection;

Es gibt verschiedene Möglichkeiten, dies zu tun: Erstellen Sie entweder ein neues Modul mit einem eigenen Controller, Block und Modell, das dem Magier-Kategoriemodul sehr ähnlich ist, oder überschreiben Sie das Magier-Kategoriemodul, um die obige Sammlung nur dann auszuführen, wenn der Kunde eine spezielle Kategorie auswählt. Dies kann einfach in der System -> Konfiguration Ihres Moduls konfiguriert werden.

Wenn Sie ein paar Pfund ausgeben können, würde ich die folgende Erweiterung für Magento Connect empfehlen

Für Magento 1 -:

http://www.magentocommerce.com/magento-connect/dynamic-sale-category.html ( http://www.scommerce-mage.co.uk/magento-dynamic-sale-category.html) )

Für Magento 2 -:

https://www.scommerce-mage.com/magento2-dynamic-sale-category.html

Ich hoffe es hilft!

Prost S

Stevensagaar
quelle
0

Ich habe eine Erweiterung für Magento 2 erstellt, die Produkte auf einem eigenen Controller mit geschichteter Navigation anzeigt. Also keine Notwendigkeit für Kategorie oder Cron.

https://github.com/DominicWatts/Special

Hoffe das hilft jemandem

Dominic Xigen
quelle