Все о бизнесе

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

И вот случилось чудо, спустя 4-5 лет долгих костылей и просьб на сайте разработчика, в API была добавлена возможность сортировать с учетом валюты.

Использование сортировки цен с валютой в 1C-Bitrix версии 16.0.3 и старше

Для того что бы использовать эту возможность, надо посмотреть в вашей системе, какой тип цены является базовы, для этого идем в Магазин → Настройки → Типы цен


"ELEMENT_SORT_FIELD" => "CATALOG_PRICE_SCALE_1", "ELEMENT_SORT_ORDER" => "desc",

Или возрастанию:

"ELEMENT_SORT_FIELD" => "CATALOG_PRICE_SCALE_1", "ELEMENT_SORT_ORDER" => "asc",

Так же, вы можете добавить 2 параметр сортировки с ключем ELEMENT_SORT_FIELD2 и ELEMENT_SORT_ORDER2.

Но что делать тем, у кого версия битрикса младше 16.0.3?

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

Для начала, нам нужно создать свойство: PRICE_SORT, в название я написал «Цена в рублях для сортировки», тип: число.

Function update_catalog_price_sort(){ $count = 0; try{ $arFilter = Array("IBLOCK_ID" => 2); $res = CIBlockElement::GetList(Array(), $arFilter, false, false, Array("ID", "PROPERTY_PRICE_SORT", "CATALOG_GROUP_1")); while($row = $res->GetNext()) { $price = $row["CATALOG_PRICE_1"]; echo "Start update {$row["ID"]}: {$price} {$row["CATALOG_CURRENCY_1"]} to "; if ($row["CATALOG_CURRENCY_1"] != "RUB"){ $price = CCurrencyRates::ConvertCurrency($price, $row["CATALOG_CURRENCY_1"], "RUB"); } if ($price != $row["PROPERTY_PRICE_SORT_VALUE"]){ CIBlockElement::SetPropertyValuesEx($row["ID"], 2, array("PRICE_SORT" => $price)); echo "{$price} {RUB} - DONE \n"; $count++; sleep(0.2); } else { echo "{$price} {RUB} - NOT NEED UPDATE \n"; } } } catch(Exception $ex) { smail("Запуск обновления цен-сортировок", "Провал - обновления:" . $ex->getMessage()); } return $count; }

Вначале мы запрашиваем все товары в системе, у меня около 120 тыс. Из запроса мы получаем:

  • ID - индификатор товара
  • CATALOG_PRICE_1 — цена товара. Учтите, что если у вас, базовый тип цены другой (смотри выше где можно проверить), то и цифра в конце ключа, будет другой. В любом случае, вы всегда можете сделать print_r($row) и узнать правильность ID базовой цены
  • CATALOG_CURRENCY_1 — в какой валюте сохранена цена. Так же как и с ценой, важно учитывать ID в конце ключа

$price = CCurrencyRates::ConvertCurrency($price, $row["CATALOG_CURRENCY_1"], "RUB");

и потом полученную цену сравниваем с тем, что у нас сохранено в PRICE_SORT (ключ в массиве: PROPERTY_PRICE_SORT_VALUE), если цены различаются, обновляем.

Для отладки я использую вывод информации и отлов исключения, с уведомление на почту. Дальше нам остается функцию update_catalog_price_sort() поместить в агент, который будет обновлять цены. Я его добавил в агент обновляющий валюту. Он у меня запускается раз в сутки, когда на сервере минимальная нагрузка.

Учтите важный момент! Это ресурсоёмкая задача, по-этому агенты должны исполняться на cron.

Ну и самое важное, прописываем наше поле PRICE_SORT в вызове компонента:

"ELEMENT_SORT_FIELD" => "PROPERTY_PRICE_SORT",

Надеюсь эта статья будет вам полезна, если вы нашли ошибки или опечатки, пишите в комментариях.

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

Чтобы мы смогли сортировать товар по цене нам нужно изначально вывести свойство в товаре с минимальной ценой. Тесть в дальнейшем мы с тобой напишем код, чтобы за нас все это делал Битрикс, проставил в каждом товаре мин. цену. из торг.предложений по которой мы и будем настраивать нашу сортировку. Надеюсь понятно, если нет то вот еще один пример за чем мы это делаем. Товар он по сути один, ну пусть это будут, тапочки домашние мужские, у этих тапочек есть разные размеры 39, 40, 41, 42 и тд. и у каждого размера может быть своя цена 100р, 200р, 300р и тд. Соответсвенно тут встает вопрос, товар один а цен у него много, а наша задача сделать сортировку, именно по цене для товара.

Давай теперь создадим то самое свойство, для мин. цены товара. Идем в настройки ИБ (Инфоблока) нашего каталога, вкладка свойство и создаем тут новое свойство, называние «Минимальная цена», тип «Число», код «MINIMUM_PRICE»

Отлично свойство у нас готово, теперь давай заглянем под капот и все там настроим. Открываем наш редактор кода и подключаемся к нашему сайту. Весь процесс будет проходить в папке local. Открываем local/php_interface/init.php, если у тебя в структуре твоего проекта нет этих папок их нужно создать. Открываем фил init.php и в него кидаем вот этот код:

class ElementSever

Array("catalog_PRICE_1" => "ASC"),

"PROPERTY_CML2_LINK" => $arFields["ID"],

"IBLOCK_ID" => $skuIblock

array("nTopCount" => "1"),

$artSku = array();

while ($element = $res->Fetch()) {

$artSku = $element;

\CIBlockElement::SetPropertyValuesEx($arFields["ID"], $arFields["IBLOCK_ID"], array("MINIMUM_PRICE" =>

Каждую строчку кода и что за что отвечает описывать не буду. Думаю, что кто в теме поймет, ну а если ты не в теме ищи того кто в ней.

В autoload_register (Автозагрузка классов) который в самом верху мы указали, что наши классы будут лажать в папке local/lib/… в ней мы и продолжим нашу работу. Создадим наши папки local/lib/ и в папке lib я создам еще одну папку и назову ее AB (AbraXabra))) нужна она для того, чтобы наши классы если они будут иметь одинаковые имена не путались. И так вот какой путь из папок получился у меня local/lib/AB в папке AB создаем собственно наш класс и называем его ElementSever.php и в него кидаем вот этот код:

class ElementSever

public static function setPrise(&$arFields)

if ($arFields["IBLOCK_ID"] == 2) {

$res = \CIBlockElement::GetList(

Array("catalog_PRICE_1" => "ASC"),

"PROPERTY_CML2_LINK" => $arFields["ID"],

"IBLOCK_ID" => $skuIblock

array("nTopCount" => "1"),

array("ID", "IBLOCK_ID", "CATALOG_GROUP_1")

$artSku = array();

while ($element = $res->Fetch()) {

$artSku = $element;

\CIBlockElement::SetPropertyValuesEx($arFields["ID"], $arFields["IBLOCK_ID"], array("MINIMUM_PRICE" => intval($artSku["CATALOG_PRICE_1"])));

В данном файле описана все логика нашего приложение. Сохраняем наш файл и двигаем дальше.

Открываем папку, где лежит наш компонент каталог, а точнее нам нужен файл section.php для старых шаблонах, для новых либо section_horizontal.php или section_vertical.php в зависимости от расположения на сайте. Ищем там, где лежит наш компонент catalog.section и перед ним нужно вставить следующий код:

if ($request->get("PROPERTY_MINIMUM_PRICE")) {

$arParams["ELEMENT_SORT_FIELD"] = "PROPERTY_MINIMUM_PRICE";

$arParams["ELEMENT_SORT_ORDER"] = $request->get("PROPERTY_MINIMUM_PRICE");

Данный кусок коды отвечает за сортировку от большего к меньшему или наоборот.

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


/** @var \Bitrix\Main\HttpRequest $request */

$request = \Bitrix\Main\Context::getCurrent()->getRequest();

use Bitrix\Main\Web;

$Uri = new Web\Uri($request->getRequestUri());

$Uri->addParams(["PROPERTY_MINIMUM_PRICE" => "ASC"]);

if ($request->get("PROPERTY_MINIMUM_PRICE") == "ASC") {

$Uri->addParams(["PROPERTY_MINIMUM_PRICE" => "DESC"]);


После того как наш url готов, вставляем его в кнопку:

getUri()?>">Сортировка по цене


Вот и все! Можем перейти на сайт в любой раздел каталога и проверить как все работает. Все спасибо тебе большое за внимание, спокойной ночи))

Исторически так сложилось, что комплексный компонент 1С-Битрикс не позволяет пользователю в публичной части отсортировать товары, хотя бы по цене, дате, наименованию, а также выбрать сколько товаров на странице ему выбрать. Но ни один из интернет-магазинов не обходится без такого функционала, который кстати включен в почти все шаблоны готовых интернет-магазинов в Маркетплэйс. Но для реализовать блоки «Сортировать по: ...» и «Показать по: ...» достаточно просто. Нужно всего-лишь использовать массив $_REQUEST и метод API 1С-Битрикс GetCurPageParam() для передачи данных в этот массив.

Приступим!

Для начала определимся, что от нас хотят:

  • Вывести справа над списком товаров блок «Показать по: 18 36 54 72». (По умолчанию выводится 9).
  • Слева над списком товаров вывести блок «Сортировать по: цене, наименованию, дате».
  • Повторное нажатие на уже выбранный вариант сортировки переключает направление сортировки.
  • Дата - дата изменения, цена - отображаемая цена товара.
Пойдем по порядку и начнем с показа выбранного пользователем из предложенных количества товаров на странице.

За отображение количества товаров на странице отвечает параметр PAGE_ELEMENT_COUNT . В него мы и будем передавать выбранное пользователем количество с помощью $_REQUEST и GetCurPageParam() .

Для начала заведем соответствующую переменную и по-умолчанию присвоим ей значение заданное в параметрах компонента. А затем при клике пользователя на нужное ему количество элементов будем его модифицировать.

Следующий код предлагается размещать перед подключением компонента catalog.section . Если используется комплексный компонент catalog , то в файле в котором происходит вызов компонента catalog.section выводящего товары на нужной странице.


И теперь передадим полученное значение в компонент:

IncludeComponent("bitrix:catalog.section", ... "PAGE_ELEMENT_COUNT" => $pageElementCount, ... ?>
Теперь разберемся с сортировкой. Она не намного сложнее, за исключением того, что нам нужно проверять текущее направление и менять его. Для этого в методе GetCurPageParam() мы будем передавать два параметра sortBy и orderBy . А затем в соответствующих переменных передавать их в параметры компонента "ELEMENT_SORT_FIELD" и "ELEMENT_SORT_ORDER" соответственно. По умолчанию сортировка должна осуществляться с помощью внутреннего поля сортировки 1С-Битрикс - sort .

Проверяем направление сортировки и меняем в случае необходимости:


Выводим ссылки на сортировку:


Параметр name принимается полем "ELEMENT_SORT_FIELD" для сортировки по наименованию товара без дополнительного вмешательства а вот для даты и цены мы должны уточнить, какой из параметров элемента инфоблока мы имеем ввиду.

Для даты нам нужно значение поля "timestamp_x" , отвечающего за дату изменения. Для цены мы должны узнать наименование типа цены, которая выводится из поля элемента инфоблока. Для этого нужно распечатать массив $arItem в шаблоне компонента (в моем случае catalog.section) либо с помощью var_dump($arItem); , либо echo ""; print_r($arItem); echo " "; . Находим поле массива отвечающего за вывод цены и копируем его название, в моем случае это оказалось CATALOG_PRICE_1 . Стоит обратить внимание, что в случае с ценой использовать нужно название того поля, которые содержит значение цены без валюты.

И передадим полученные данные в переменную $sortBy:


И передадим значения в параметры компонента:

IncludeComponent("bitrix:catalog.section", ... "ELEMENT_SORT_FIELD" => $sortBy, "ELEMENT_SORT_ORDER" => $orderBy, ... ?>
Вот собственно и все. В результате получится примерно такая строка:

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

Для выполнения сортировки в компоненте news.list или catalog.section компоненту необходимо передать параметры ELEMENT_SORT_FIELD и ELEMENT_SORT_ORDER .

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

  • id - ID элемента;
  • sort - индекс сортировки;
  • timestamp_x - дата изменения;
  • name - название;
  • active_from или date_active_from - начало периода действия элемента;
  • active_to или date_active_to - окончание периода действия элемента;
  • status - код статуса элемента в документообороте;
  • code - мнемонический код элемента;
  • iblock_id - числовой код информационного блока;
  • modified_by - код последнего изменившего пользователя;
  • active - признак активности элемента;
  • show_counter - количество показов элемента (учитывается функцией CIBlockElement::CounterInc );
  • show_counter_start - время первого показа элемента (учитывается функцией CIBlockElement::CounterInc );
  • shows - усредненное количество показов (количество показов / продолжительность показа);
  • rand - случайный порядок;
  • xml_id или external_id - внешний код;
  • tags - теги;
  • created - время создания;
  • created_date - дата создания без учета времени;
  • cnt - количество элементов (только при заданной группировке).

Примечание : Поля active_from и active_to - устаревшие.

Также сортировать можно по созданным вами свойствам элемента информационного блока:

  • property_ - по значению свойства с числовым или мнемоническим кодом PROPERTY_CODE (например, PROPERTY_123 или PROPERTY_NEWS_SOURCE).
  • propertysort_ - по индексу сортировки варианта значения свойства. Только для свойств типа Список .
  • catalog__ - по полю CATALOG_FIELD (может быть PRICE - цена или CURRENCY - валюта) из цены с типом PRICE_TYPE (например, catalog_PRICE_1 или CATALOG_CURRENCY_3). Сортировка должна иметь формат: CATALOG_(PRICE или CURRENCY)_ID-типа-цены .
  • catalog_QUANTITY - сортировка по количеству.
  • PROPERTY_. - по значению поля элемента указанного в качестве привязки. PROPERTY_CODE - мнемонический или символьный код свойства типа привязка к элементам . FIELD может принимать значения:
    • TIMESTAMP_X
    • MODIFIED_BY
    • CREATED
    • CREATED_DATE
    • CREATED_BY
    • IBLOCK_ID
    • ACTIVE
    • ACTIVE_FROM
    • ACTIVE_TO
    • SHOW_COUNTER
    • SHOW_COUNTER_START
    • XML_ID
    • STATUS
  • PROPERTY_PROPERTY_ - по значению свойства элемента указанного в качестве привязки. PROPERTY_CODE - мнемонический или символьный код свойства типа привязки к элементам. PROPERTY_CODE2 - код свойства связанных элементов.
  • HAS_PREVIEW_PICTURE и HAS_DETAIL_PICTURE - сортировка по наличию и отсутствию картинок.

Примечание : Свойства catalog_*** доступны только при наличии модуля Торговый каталог .

Тип сортировки указывается в соответствии со списком:

  • asc - по возрастанию;
  • nulls,asc - по возрастанию с пустыми значениями в начале выборки;
  • asc,nulls - по возрастанию с пустыми значениями в конце выборки;
  • desc - по убыванию;
  • nulls,desc - по убыванию с пустыми значениями в начале выборки;
  • desc,nulls - по убыванию с пустыми значениями в конце выборки.

Самый простой способ передать новые параметры для сортировки в компонент - это использовать $_GET запрос и передать соответствующие переменные.

Также можно воспользоваться $_SESSION и записать переменные в массив переменных сессии. Предположим нам необходимо сделать ссылки или кнопки(название, цена, лидер продаж, дата поступления) для сортировки товаров в разделе каталога(используем комплексный компонент catalog ). После того как мы скопировали шаблон, необходимо открыть файл section.php и внести в него следующие модификации перед подключением компонента bitrix:catalog.section :

<?if ($_GET["sort"] == "name" || $_GET["sort"] == "catalog_PRICE_3" || $_GET["sort"] == "property_PRODUCT_TYPE" || $_GET["sort"] == "timestamp_x"){ $arParams["ELEMENT_SORT_FIELD"] = $_GET["sort"]; $arParams["ELEMENT_SORT_ORDER"] = $_GET["method"]; }else{}?>

Этот код необходим для изменения параметров сортировки в компоненте. Далее откроем файл template.php компонента catalog.section и добавим ссылки управления сортировками:

Сортировка: class="active" href="?sort=name&method=asc">название class="active" href="?sort=catalog_PRICE_3&method=asc">цена class="active" href="?sort=property_PRODUCT_TYPE&method=desc">лидер продаж class="active" href="?sort=timestamp_x&method=desc">дата поступления

Данную сортировку можно выполнить без перезагрузки страницы с использованием jQuery либо Bitrix Framework .

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.



Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter
ПОДЕЛИТЬСЯ:
Все о бизнесе