Utwórz stronę kategorii, która wyświetla wszystkie produkty w specjalnej cenie

12

Zasadniczo utworzyłem kategorię „Produkty w wyprzedaży”, które chciałbym automatycznie zawierać w moim katalogu wszystkie produkty, do których zastosowano specjalną cenę (poprzez Katalog> Zarządzaj produktami). Chciałbym, aby strona zachowała warstwowe możliwości nawigacji i sortowania , które zawiera standardowa strona kategorii Magento.

Wydaje się, że jest to coś, co byłoby cenne dla większości użytkowników Magento, i jestem zaskoczony, że nie jest częścią podstawowej funkcjonalności.

Próbowałem ponad tuzina odpowiedzi Stack Exchange, postów na blogu i forów i jak dotąd nic nie działało. Czy ktoś ma programowe rozwiązanie tego problemu?

=== EDYCJA ===

Opierając się na krytyce @ pspahn w poniższych komentarzach, postanowiłem zastosować alternatywną metodę osiągnięcia podobnej funkcjonalności. Powiedziawszy to, jeśli jesteś zainteresowany realizacją tej linii, @ sander-mangel opisuje metodę, która wydaje się całkowicie wykonalna.

rokkor
źródło
Wydaje mi się, że wymóg „automatycznie zawiera wszystkie produkty o specjalnych cenach” jest nieco nadmierny. Zakładam, że efekt końcowy jest taki, że chcesz mieć stronę ze specjalnymi cenami produktów i wyglądać jak strona kategorii. Wydaje się, że zamiast tego możesz po prostu stworzyć własny model / kolekcję (na podstawie produktów o specjalnej cenie) i użyć tej kolekcji w szablonach na podstawie stron widoku kategorii. Po prostu nie widzę kategorii, która jest zapełniana automatycznie, jako dobrego rozwiązania, na przykład, w jaki sposób można zapobiec modyfikowaniu jej przez użytkownika?
pspahn
@pspahn Dziękujemy za odpowiedź. Rozumiem twoją krytykę i zgadzam się z twoim rozumowaniem. Mógłbym skorzystać z metody opisanej przez Sandera Mangela z dodatkowym obserwatorem category_save_after, ale wydaje się to przesadą. Pójdę naprzód z alternatywnym rozwiązaniem.
rokkor
@pspahn - nie rozumiem, co masz na myśli, mówiąc „w jaki sposób zapobiegasz modyfikowaniu go przez użytkownika” - czy możesz wyjaśnić coś więcej?
ProxiBlue
@ProxiBlue Zasadniczo, jeśli utworzysz kategorię i zapełnisz produkty automatycznie, administrator może po prostu przejść do tej kategorii w backendie i ręcznie dodać / usunąć produkty.
pspahn
@pspahn ok, z użytkownikiem źle zrozumiałem jako użytkownika front-end.
ProxiBlue

Odpowiedzi:

8

Najłatwiejszym sposobem na to jest utworzenie niestandardowego rozszerzenia współpracującego z Obserwatorem i Cronjob.

Utwórz kategorię dla produktów sprzedaży. W ten sposób możesz używać normalnych funkcjonalności Magento w interfejsie, takich jak nawigacja warstwowa itp.

Aby automatycznie otrzymać produkty z tej kategorii, skorzystamy z obserwatora i kumpla. Obserwator będzie obserwował catalog_product_save_afterzdarzenie, które zostanie wywołane, gdy produkt zostanie zapisany w wewnętrznej bazie danych. Gdy tak się stanie, możesz sprawdzić datę special_price, special_price_fromdatę i special_date_todatę, aby określić, czy musisz umieścić produkt w kategorii sprzedaży, czy go usunąć.

Koleżanka jest na specjalne okazje i do tej pory. Każdej nocy po północy najpierw opróżnij kategorię sprzedaży wszystkich produktów. Następnie skorzystaj z kolekcji, aby wyszukać wszystkie produkty, które mają specjalną cenę i mieszczą się w specjalnej cenie od i do tej pory. Jeśli tak, przenieś je do tej kategorii sprzedaży.

Sander Mangel
źródło
7

Rozwiązanie oferowane przez @SanderMangel jest na najwyższym poziomie. Mogę pomóc rozwinąć tę kwestię za pomocą kodu, którego obecnie używam w moim module Produkty kategorii automatycznej / dynamicznej - która ma możliwość wykonywania reguł kategorii produktów na specjalnych

Kod dostosowuje standardową kolekcję produktów, aby uzyskać wszystkie produkty ze specjalną ceną w dniu uruchomienia kodu. Możesz użyć tego w cronie, aby ponownie wypełnić kategorie o 00:00 i upewnić się, że będą aktualne.

Zauważ, że kod jest pobierany z większego modułu, dlatego skompresowałem tutaj odpowiednie części. Może istnieć zmienna lub dwie, które nie są reprezentowane w wyciągu thsi, ale można je łatwo wydedukować lub po prostu zapytać :)

Obiekt $ category to faktyczna kategoria, która ma zawierać produkty. Poniższy kod pozwoli ci również określić rabat w wartości% :)

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

Należy zauważyć, że kolekcja nie zwróci produktów, ponieważ zawiera linki do normalnych tabel linków do katalogu <-> produktów. Ponieważ nie jesteś zainteresowany obecnymi połączonymi produktami, musisz usunąć tę relację tabeli z kolekcji.

Używam następującego kodu, aby to zrobić:

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

jako dodatkowy bonus, możesz użyć tej samej teorii do dostosowania kolekcji produktów z katalogu i znaleźć produkty, które są w trybie specjalnym ze względu na reguły katalogu:

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

Gdy masz już działającą kolekcję, wszystko, co musisz zrobić, to pobrać wszystkie identyfikatory z kolekcji, odwrócić tablicę i użyć $category->setPostedProducts($products);oraz $ category-> save () l; aby zakończyć aktualizację.

Dla kompletności, oto mój codzienny cron, który aktualizuje kategorie dynamiczne. (znowu odnosi się do metod nieuwzględnionych tutaj, ale jestem pewien, że poprowadzi cię we właściwym kierunku

Baw się dobrze :)

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
źródło
5

Oto kolekcja, która powinna dać ci zestaw wyników wszystkich specjalnych produktów cenowych w twoim katalogu, które możesz wyświetlić na jednej stronie

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

Można to zrobić na kilka sposobów: utwórz nowy moduł, który ma własny kontroler, blok i model bardzo podobny do modułu kategorii Mag lub przesłonisz moduł kategorii Mag, aby uruchomić powyższą kolekcję tylko wtedy, gdy klient wybierze kategorię specjalną. Można to łatwo skonfigurować w systemie -> konfiguracja modułu.

Jeśli możesz wydać kilka funtów, polecam następujące rozszerzenie Magento Connect

Dla Magento 1 -:

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

Dla Magento 2 -:

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

Mam nadzieję, że to pomoże!

Pozdrawiam S.

stevensagaar
źródło
0

Stworzyłem rozszerzenie dla Magento 2, które wyświetla specjalne produkty pod własnym kontrolerem z nawigacją warstwową. Więc nie ma potrzeby kategorii ani crona.

https://github.com/DominicWatts/Special

Mam nadzieję, że to komuś pomoże

Dominic Xigen
źródło