Страница «Создать категорию», на которой отображаются все продукты по специальной цене.

12

По сути, я создал категорию «Продукты в продаже», в которую я хотел бы автоматически включить все продукты из моего каталога, к которым была применена специальная цена (через Каталог> Управление продуктами). Я хотел бы, чтобы страница сохранила многоуровневую навигацию и возможности сортировки , которые содержит стандартная страница категории Magento.

Кажется, что это то, что было бы полезно большинству пользователей Magento, и я удивлен, что это не входит в базовую функциональность.

Я перепробовал более десятка ответов Stack Exchange, сообщений в блогах и форумах, и пока ничего не получалось. У кого-нибудь есть программное решение для этого?

=== РЕДАКТИРОВАТЬ ===

Основываясь на критике @ pspahn в комментариях ниже, я решил использовать альтернативный метод достижения аналогичной функциональности. С учетом вышесказанного, если вы заинтересованы в продолжении этой линии, @ sander-mangel описывает метод, который кажется вполне осуществимым.

rokkor
источник
Мне кажется, что требование «автоматически содержать все продукты со специальной ценой» является несколько чрезмерным. Я предполагаю, что конечный результат заключается в том, что вам нужна страница со специальными ценовыми продуктами, которая выглядит как страница категории. Похоже, вы могли бы вместо этого просто создать свою собственную модель / коллекцию (на основе продуктов со специальной ценой) и использовать эту коллекцию в шаблонах на основе страниц просмотра категорий. Я просто не вижу категории, которая автоматически заполняется, как хорошее решение, например, как вы можете предотвратить изменение пользователем?
pspahn
@pspahn Спасибо за ваш ответ. Я понимаю вашу критику и согласен с вашей аргументацией. Я мог бы использовать метод, описанный Сандером Мангелем с дополнительным наблюдателем category_save_after для хорошей меры, но это кажется излишним. Я пойду вперед с альтернативным решением.
Роккор
@pspahn - я не понимаю, что вы имеете в виду под «как вы предотвращаете изменение пользователем» - можете ли вы объяснить немного дальше?
ProxiBlue
@ProxiBlue В основном, если вы создаете категорию и автоматически заполняете ее продуктами, пользователь-администратор может просто зайти в эту категорию в бэкэнде и добавить / удалить продукты вручную.
pspahn
@pspahn Хорошо, с пользователем, которого я неправильно понял как пользователь переднего плана.
ProxiBlue

Ответы:

8

Самый простой способ сделать это - создать собственное расширение, которое работает с Observer и Cronjob.

Создайте категорию для продажи товаров. Таким образом, вы можете использовать обычные функции Magento во внешнем интерфейсе, такие как многоуровневая навигация и т. Д.

Для автоматического получения товаров в этой категории мы будем использовать наблюдателя и cronjob. Наблюдатель будет наблюдать за catalog_product_save_afterсобытием, которое запускается при сохранении продукта в бэкэнде. Когда это произойдет , вы можете проверить special_price, special_price_fromдату и special_date_toдату , чтобы определить , если вам нужно поместить продукт в категорию продаж или удалить его оттуда.

Cronjob там для специальных от и до даты. Каждую ночь после полуночи сначала очищайте категорию продаж всех продуктов. Затем используйте коллекцию, чтобы получить все продукты, которые имеют специальную цену и попадают в специальные с и до даты. Если это так, переместите их в эту категорию продаж.

Сандер Мангель
источник
7

Решение, предлагаемое @SanderMangel, на высшем уровне. Я могу помочь расширить это с помощью некоторого кода, который я в настоящее время использую в своем модуле «Автоматическая / Динамическая категория продуктов», который имеет возможность выполнять правила категорий продуктов на специальных

Код настраивает стандартную коллекцию продуктов, чтобы получать все продукты с установленной специальной ценой в день запуска кода. Вы можете использовать это в cron для повторного заполнения категорий в 00:00 и проверки их актуальности.

Обратите внимание, что код извлекается из более крупного модуля, поэтому я сжал для вас соответствующие части. Может быть переменная или две, которые не представлены в этом извлечении, но их будет легко вывести, или просто спросить :)

Объект $ category - это фактическая категория, которая должна содержать продукты. Код ниже также позволит вам указать скидку в% значении :)

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

Теперь следует отметить, что коллекция не будет возвращать товары, так как она содержит ссылки на обычный каталог <-> таблиц ссылок на товары. Поскольку вас не интересуют текущие связанные продукты, вам необходимо удалить это табличное отношение из коллекции.

Я использую следующий код, чтобы сделать это:

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

в качестве дополнительного бонуса вы можете использовать ту же технику при настройке коллекции продуктов каталога и находить продукты, которые находятся в специальном режиме благодаря правилам каталога:

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

Когда у вас есть рабочая коллекция, все, что вам нужно сделать, это получить все идентификаторы из коллекции, перевернуть массив и использовать $category->setPostedProducts($products);и $ category-> save () l; завершить обновление.

Для полноты, вот мой ежедневный хрон, который поддерживает динамические категории в актуальном состоянии. (опять же, это относится к методам, не включенным здесь, но я уверен, что это поможет вам в правильном направлении

Веселиться :)

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

ссылка: http://www.proxiblue.com.au/magento-dynamic-category-products.html

ProxiBlue
источник
5

Вот коллекция, которая должна дать вам набор результатов всех продуктов со специальной ценой в вашем каталоге, которые вы можете отобразить на одной странице.

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

Это можно сделать несколькими способами: либо создать новый модуль с собственным контроллером, блоком и моделью, очень похожим на модуль категории «Маг», либо переопределить модуль категории «Маг», чтобы запускать вышеуказанную коллекцию только тогда, когда заказчик выбрал специальную категорию. Это можно легко настроить в системе -> настройка вашего модуля.

Если вы можете потратить несколько фунтов, я бы порекомендовал следующее расширение для подключения Magento.

Для Magento 1 -:

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

Для Magento 2 -:

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

Надеюсь, это поможет!

Приветствия S

stevensagaar
источник
0

Я создал расширение для Magento 2, которое отображает продукты на специальных устройствах под собственным контроллером с многоуровневой навигацией. Так что нет необходимости в категории или хрон.

https://github.com/DominicWatts/Special

Надеюсь, это поможет кому-то

Доминик Ксиген
источник