Обновление Bitrix Эксперт

На днях пришёл запрос на продление БУС лицензии "Эксперт", пришлось выяснять, что это за архивный тип лицензии...
Выяснилось, что БУС лицензии "Эксперт" сопоставим с БУС "Стандарт" по ценам и доступным модулям.

Редакция "Эксперт" больше, чем "Малый Бизнес", но нет модуля "Интернет магазин".
Редакция "Стандарт" не имеет таких модулей как "E-mail маркетинг", "Реклама" и "Веб-аналитика" а так же в 2 раза уменьшается размер облачного бэкапа.
( сравнение актуальных редакций https://www.1c-bitrix.ru/products/cms/license.php )
Если переходить на редакцию "Малый бизнес":
- стоимость перехода 20 000 руб.
- стоимость продления 8 975 руб.
понизить до редакции "Стандарт" (подписать документ "" и отправить в Битрикс), а потом покупать переход + продление

Если переходить на младшую редакцию "Стандарт":
- стоимость перехода 0 руб.
- стоимость продления 3 975 руб.
понизить до редакции "Стандарт" (подписать документ и отправить в Битрикс),

D7 Выбора товаров + SKU + разделы одним запросом

Рабочий пример:
$sql = [
    'select' => [
        "ID",
    ],
    'runtime' => [
        new \Bitrix\Main\Entity\ReferenceField( // получим свойство связи с SKU
            'CML2_LINK',
            '\Bitrix\Iblock\PropertyTable',
            [
                "=ref.CODE" => new \Bitrix\Main\DB\SqlExpression('?', 'CML2_LINK'),
            ],
            ["join_type" => "left"]
        ),
        new \Bitrix\Main\Entity\ReferenceField( // получим свойство артикула
            'CML2_ARTICLE',
            '\Bitrix\Iblock\PropertyTable',
            [
                "=ref.CODE" => new \Bitrix\Main\DB\SqlExpression('?', 'CML2_ARTICLE'),
            ],
            ["join_type" => "left"]
        ),
        new \Bitrix\Main\Entity\ReferenceField( // получим свойство штрихкода
            'CML2_BAR_CODE',
            '\Bitrix\Iblock\PropertyTable',
            [
                "=ref.CODE" => new \Bitrix\Main\DB\SqlExpression('?', 'CML2_BAR_CODE'),
            ],
            ["join_type" => "left"]
        ),
        new \Bitrix\Main\Entity\ReferenceField(
            'SKU_LINK_ID',
            '\Bitrix\Iblock\ElementPropertyTable',
            [
                "=this.ID" => "ref.VALUE",
                "=this.CML2_LINK.ID" => "ref.IBLOCK_PROPERTY_ID",
            ],
            ["join_type" => "inner"]
        ),
        new \Bitrix\Main\Entity\ReferenceField(
            'SKU_ITEM',
            '\Bitrix\Iblock\ElementTable',
            [
                "=this.SKU_LINK_ID.IBLOCK_ELEMENT_ID" => "ref.ID",
            ],
            ["join_type" => "left"]
        ),
        new \Bitrix\Main\Entity\ReferenceField(
            'SKU_ITEM_PROPERTY_CML2_ARTICLE',
            '\Bitrix\Iblock\ElementPropertyTable',
            [
                "=this.SKU_ITEM.ID" => "ref.IBLOCK_ELEMENT_ID",
                "=this.CML2_ARTICLE.ID" => "ref.IBLOCK_PROPERTY_ID",
            ],
            ["join_type" => "left"]
        ),
        new \Bitrix\Main\Entity\ReferenceField(
            'SKU_ITEM_PROPERTY_CML2_BAR_CODE',
            '\Bitrix\Iblock\ElementPropertyTable',
            [
                "=this.SKU_ITEM.ID" => "ref.IBLOCK_ELEMENT_ID",
                "=this.CML2_BAR_CODE.ID" => "ref.IBLOCK_PROPERTY_ID",
            ],
            ["join_type" => "left"]
        ),
        new \Bitrix\Main\Entity\ReferenceField(
      'SECTION',
      '\Bitrix\Iblock\SectionTable',
      [
         "=this.IBLOCK_SECTION_ID" => "ref.ID",
      ],
      ["join_type" => "left"]
   ),
   new \Bitrix\Main\Entity\ReferenceField(
      'TOP_SECTION',
      '\Bitrix\Iblock\SectionTable',
      [
         ">this.SECTION.LEFT_MARGIN" => "ref.LEFT_MARGIN",
         "<this.SECTION.RIGHT_MARGIN" => "ref.RIGHT_MARGIN",
         "=ref.DEPTH_LEVEL" => new \Bitrix\Main\DB\SqlExpression('?', '1'),
      ],
      ["join_type" => "left"]
   ),

    ],
    'group' => [
        'ID',
        //'SKU_ITEM.ID',
    ],
    'filter' => [
        "ACTIVE" => "Y",
        "IBLOCK_ID" => $arParams["IBLOCK_ID"], // только товары 
        "!=TOP_SECTION.CODE" => $_SESSION["SKIP_INDEX_SECTION_CODE"],
    ],
    'order' => ['ID' => "ASC"],
    'cache' => ($arParams["CACHE_TYPE"] != "N" ? ["ttl" => $arParams["CACHE_TIME"], "cache_joins" => true] : null),
    'limit' => 50000
];
$iterator = \Bitrix\Iblock\ElementTable::getList($sql);
while ($filtredElementArr = $iterator->fetch()) {
    $ids[] = $filtredElementArr["ID"];
}


Генерируется примерно такой запрос:
SELECT 
   `iblock_element`.`ID` AS `ELEMENT_ID`
FROM `b_iblock_element` `iblock_element` 
LEFT JOIN `b_iblock_property` `iblock_element_cml2_link` ON `iblock_element_cml2_link`.`CODE` = 'CML2_LINK'
LEFT JOIN `b_iblock_property` `iblock_element_cml2_article` ON `iblock_element_cml2_article`.`CODE` = 'CML2_ARTICLE'
LEFT JOIN `b_iblock_property` `iblock_element_cml2_bar_code` ON `iblock_element_cml2_bar_code`.`CODE` = 'CML2_BAR_CODE'
INNER JOIN `b_iblock_element_property` `iblock_element_sku_link_id` ON `iblock_element`.`ID` = `iblock_element_sku_link_id`.`VALUE`
AND `iblock_element_cml2_link`.`ID` = `iblock_element_sku_link_id`.`IBLOCK_PROPERTY_ID`
LEFT JOIN `b_iblock_element` `iblock_element_sku_item` ON `iblock_element_sku_link_id`.`IBLOCK_ELEMENT_ID` = `iblock_element_sku_item`.`ID`
LEFT JOIN `b_iblock_element_property` `iblock_element_sku_item_property_cml2_article` ON `iblock_element_sku_item`.`ID` = `iblock_element_sku_item_property_cml2_article`.`IBLOCK_ELEMENT_ID`
AND `iblock_element_cml2_article`.`ID` = `iblock_element_sku_item_property_cml2_article`.`IBLOCK_PROPERTY_ID`
LEFT JOIN `b_iblock_element_property` `iblock_element_sku_item_property_cml2_bar_code` ON `iblock_element_sku_item`.`ID` = `iblock_element_sku_item_property_cml2_bar_code`.`IBLOCK_ELEMENT_ID`
AND `iblock_element_cml2_bar_code`.`ID` = `iblock_element_sku_item_property_cml2_bar_code`.`IBLOCK_PROPERTY_ID`
LEFT JOIN `b_iblock_section` `iblock_element_section` ON `iblock_element`.`IBLOCK_SECTION_ID` = `iblock_element_section`.`ID`
LEFT JOIN `b_iblock_section` `iblock_element_top_section` ON `iblock_element_section`.`LEFT_MARGIN` > `iblock_element_top_section`.`LEFT_MARGIN`
AND `iblock_element_section`.`RIGHT_MARGIN` < `iblock_element_top_section`.`RIGHT_MARGIN`
AND `iblock_element_top_section`.`DEPTH_LEVEL` = '1'
WHERE UPPER(`iblock_element`.`ACTIVE`) like upper('Y')
AND `iblock_element`.`IBLOCK_ID` = 17
AND (`iblock_element_top_section`.`CODE` IS NULL OR `iblock_element_top_section`.`CODE` not in ('rasprodazha_20'))
ORDER BY `ELEMENT_ID` ASC
LIMIT 0, 50

CMS bitrix таблица b_sale_product2product

В CMS bitrix таблица b_sale_product2product - отвечает за функционал «с этим товаром также покупают»

Штатными средствами можно отключить: Настройки продукта > Настройки модулей > Интернет-магазин > Настройки также продаваемых продуктов.  

Создание обработчика доставки для 1С-Битрикс (метод 2012 года)

Старый метод, позволяет понять некоторые вещи в работе доставки.

Разработчики, которые делают проекты на Битрикс, хорошо знакомы с двумя типами служб доставки в этой CMS — это Настраиваемые и Автоматизированные. В этой статье мы посмотрим как сделать свой Автоматизированный обработчик доставки и даже сделаем простой пример такого обработчика.

Об автоматизированном обработчике доставки

Все предустановленные обработчики располагаются в папке /bitrix/modules/sale/lang/ru/delivery/ . Свои обработчики следует располагать в папке /bitrix/php_interface/include/sale_delivery/ (этот путь можно изменить в свойствах модуля интернет-магазина). Обработчик представляет собой класс определенной структуры со строкой подключения обработчика доставки по событию onSaleDeliveryHandlersBuildList .

Класс обработчика доставки должен иметь ряд методов, типы действий которых, описываются в методе Init класса.

Эти методы такие:

1. Init — происходит инициализации основных полей.

2. DBGETSETTINGS  — метод считывания значений параметров.

3. DBSETSETTINGS  — метод установки значений параметров.

4. GETCONFIG — определение конфигурации настроек (их можно разбить на табы).

5. COMPABILITY — проверка совместимости профилей обработчика с заказом.

6. CALCULATOR — расчет стоимости доставки.

Также должны быть заданы поля:

1. SID  —  Уникальный строковой идентификатор обработчика.
2. NAME —  Название обработчика.
3. DESCRIPTION — Текстовое описание обработчика
4. DESCRIPTION_INNER — Внутреннее описание обработчика, отображаемое при конфигурации обработчика в Панели Управления.
5. BASE_CURRENCY — Идентификатор базовой валюты обработчика
6. HANDLER — Путь к файлу обработчика. Нужен для корректного автоматического копирования обработчика (ещё не реализовано). В подавляющем большинстве случаев достаточно значения __FILE__

Также должны быть заданы профили доставки. Хотя бы один.

Простейший обработчик доставки.

Не будем мудрить — сделаем обработчик, который ничего не считает и всегда выдает цену одну и ту же, например 200 руб. В нем будет всего один профиль — без ограничений. В настройки вынесем цену доставки.

class CDeliveryPlain
{

    /**
     * Описние обработчика
     */
    function Init()
    {
        //настройки
        return array(
            "SID"                     => "Plain",  // Идентификатор службы доставки
            "NAME"                     => "Пример обработчика службы доставки",
            "DESCRIPTION"             => "Описание его для клиентов сайта",
            "DESCRIPTION_INNER"     => "Описание для администраторов сайта",
            "BASE_CURRENCY"         => "RUR",

            "HANDLER"                 => __FILE__,

            /* Определение методов */
            "DBGETSETTINGS"         => array("CDeliveryPlain", "GetSettings"),
            "DBSETSETTINGS"         => array("CDeliveryPlain", "SetSettings"),
            "GETCONFIG"             => array("CDeliveryPlain", "GetConfig"),

            "COMPABILITY"             => array("CDeliveryPlain", "Compability"),
            "CALCULATOR"             => array("CDeliveryPlain", "Calculate"),

            /* Список профилей */
            "PROFILES" => array(
                "all" => array(
                    "TITLE" => "Без ограничений",
                    "DESCRIPTION" => "Профиль доставки без каких-либо ограничений",

                    "RESTRICTIONS_WEIGHT" => array(0),
                    "RESTRICTIONS_SUM" => array(0),
                ),
            )
        );
    }

    /* Установка параметров */
    function SetSettings($arSettings)
    {
        foreach ($arSettings as $key => $value) {
            if (strlen($value) > 0)
                $arSettings[$key] = doubleval($value);
            else
                unset($arSettings[$key]);
        }

        return serialize($arSettings);
    }

    /* Запрос параметров */
    function GetSettings($strSettings)
    {
        return unserialize($strSettings);
    }

    /* Запрос конфигурации службы доставки */
    function GetConfig()
    {
        $arConfig = array(
            "CONFIG_GROUPS" => array(
                "all" => "Параметры",
            ),

            "CONFIG" => array(
                "DELIVERY_PRICE" => array(
                    "TYPE" => "STRING",
                    "DEFAULT" => "200",
                    "TITLE" => "Стоимость доставки",
                    "GROUP" => "all"
                )
            ),
        );
        return $arConfig;
    }

    /* Проверка соответствия профиля доставки заказу */
    function Compability($arOrder, $arConfig)
    {
        return array("all");
    }

    /* Калькуляция стоимости доставки*/
    function Calculate($profile, $arConfig, $arOrder, $STEP, $TEMP = false)
    {
        return array(
            "RESULT" => "OK",
            "VALUE" => $arConfig["DELIVERY_PRICE"]
        );
    }
}

AddEventHandler("sale", "onSaleDeliveryHandlersBuildList", array("CDeliveryPlain", "Init"));


Сохраним этот обработчик в файле /bitrix/php_interface/include/sale_delivery/delivery_plain.php и посмотрим в список автоматизированных обработчиков. Если мы видим его в списке, то значит все сделано правильно. Нам осталось его активировать и проверить работу.

Информация взята с http://blog.sokov.org/sozdanie-obrabotchika-dostavki-dlya-1s-bitriks/

Как публиковать UserID в Yandex метрику (1C-Bitrix)

Для получения внешнего кода пользователя можно использовать PHP код:
$GLOBALS["USER"]->GetParam('XML_ID');  // или  $GLOBALS["USER"]->GetID();
Для передачи параметров пользователя в Yandex метрику можно использовать код JS:
window.onload = function () {
    try {
        if ({{Полученный в PHP UserID пользователя}}) {
            ym({{код счётчика}}, 'userParams', {
                vip_status: false,
                UserID: {{Полученный в PHP UserID пользователя}}
            });
        }
    } catch (e) {
        console.log("Ошибка отправки UserID");
    }
};


Вопросы и замечания прошу писать ниже в комментариях

Пресет в main.ui.filter

Вот как бы нет нареканий к большущим компонентам main.ui.filter и main.ui.grid, но я нигде не видел рабочий код для передачи данных для пресета фильтра и последующей фильтрации выборки для main.ui.grid.

Фокус в том, что пресет задаётся до вызова этих компонентов, и выбранный "по умолчанию" должен примениться к выборке main.ui.grid.
Что бы это реализовать в компоненте в месте где получаем и проверяем значения фильтра делаем так:
$arResult['GRID']['FILTER_ID'] = (str)$arParams['FILTER_ID];
$arResult['GRID']['FILTER_FIELDS'] =  $arParams['FILTER_FIELDS] // массив полей фильтра
$arResult['GRID']['FILTER_OBJ'] = new Bitrix\Main\UI\Filter\Options($arResult['GRID']['FILTER_ID'], $arParams['FILTER_PRESETS']); // либо запилить пресет прямо в компонент.
$filterData = $arResult['GRID']['FILTER_OBJ']->getFilter($arResult['GRID']['FILTER_FIELDS']); // получили массив для фильтрации

Фильтруем! :)

Страницы: 1 | 2 | 3 | След.