Заполнить коэффициент единицы измерения (MEASURE_RATIO) из свойства элемента

Просмотров: 11532

Задача: Каталог наполняется из 1С, но 1С не передает коэффициент единицы измерения (особенность конкретной 1С, но вообще она умеет). Вместо этого, коэффициенты забиваются в обычный, дополнительный реквизит и приходят на сайт как свойство. Нужно заполнить коэффициент из этого поля.

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

Заполнить коэффициент единицы измерения (MEASURE_RATIO) из свойства элемента

Скрипт для запуска в ручную, по крону или на событие в init.php:

Cmodule::IncludeModule('iblock');
Cmodule::IncludeModule('catalog');
$iblockId = 4;
$updateElements = CIBlockElement::GetList(
    array("ID" => "ASC"),
    array("IBLOCK_ID" => $iblockId),
    false,
    false,
    array(
        'ID',
        'PROPERTY_ATT_COEFFFICIENT'
    )
);
while ($arFields = $updateElements ->GetNext()) {
    $coeff = $arFields['PROPERTY_ATT_COEFFFICIENT_VALUE'];
    $curElementRatio = CCatalogMeasureRatio::getList(
        false,
        array(
            'IBLOCK_ID' => $iblockId,
            'PRODUCT_ID' => $arFields['ID']),
        false,
        false);
    while ($arRatio = $curElementRatio->GetNext()) {
        $ratioId = $arRatio['ID'];
    }

    CCatalogMeasureRatio::update($ratioId, array(
            'PRODUCT_ID' => $arFields['ID'],
            'RATIO' => $coeff
        )
    );
}

Пояснения:
C помощью CIBlockElement::GetLis - получили элементы инфоблока с ИД 4.
Нам нужны только ID элементов и значение свойства PROPERTY_ATT_COEFFFICIENT
Значение коэффициента загнали в переменную $coeff

Внутри цикла (каждого элемента), с помощью CCatalogMeasureRatio::getList получили ID коэффициента конкретного товара (элемента) и загнали в переменную $ratioId
С помощью CCatalogMeasureRatio::update перезаписали/установили коэффициенты для конкретного товара

PS: Если коэффициентов еще не было (пустые). Можно их создать, тут же в цикле, методом CCatalogMeasureRatio::add с любым значением. И тут же перезаписать. Или сразу добавить с нужным значением.

У заметки есть дополнение: Массово изменить коэффициент единицы измерения

Заполнить коэффициент единицы измерения используя D7

Этот код использует D7-синтаксис для работы с таблицами и модулями в 1С-Битрикс. Обратите внимание, что в D7 нет необходимости использовать CModule::IncludeModule, так как в коде выше используется Loader::includeModule.

use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;
use Bitrix\Catalog\MeasureRatioTable;
Loader::includeModule('iblock');
Loader::includeModule('catalog');

$iblockId = 4;
$updateElements = ElementTable::getList([
    'select' => ['ID'],
    'filter' => ['IBLOCK_ID' => $iblockId],
]);
while ($arFields = $updateElements->fetch()) {
    $propertyValue = CIBlockElement::GetProperty(
        $iblockId,
        $arFields['ID'],
        [],
        [
                'CODE' => 'KV_METROV_V_UPAKOVKE_CHIS'
        ]
    );

    if ($arProperty = $propertyValue->Fetch()) {
        $coeff = $arProperty['VALUE'];

        $curElementRatio = MeasureRatioTable::getList([
            'filter' => [
                '=PRODUCT_ID' => $arFields['ID'],
            ],
        ]);
        if ($arRatio = $curElementRatio->fetch()) {
            MeasureRatioTable::update($arRatio['ID'], [
                'RATIO' => $coeff,
            ]);
        }
    }
}

Обновлление коэффициента на событиях обновления или добавления элементов

Для того чтобы сделать код срабатывающим на событиях OnAfterIBlockElementAdd и OnAfterIBlockElementUpdate, вы можете зарегистрировать обработчик событий, используя следующий код в файле init.php:

use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;
use Bitrix\Catalog\MeasureRatioTable;

Loader::includeModule('iblock');
Loader::includeModule('catalog');

function updateMeasureRatiosAfterElementChange(&$arFields) {
    if ($arFields['IBLOCK_ID'] == 4) {
        $propertyValue = CIBlockElement::GetProperty(
            $arFields['IBLOCK_ID'],
            $arFields['ID'],
            [],
            ['CODE' => 'KV_METROV_V_UPAKOVKE_CHIS']
        );

        if ($arProperty = $propertyValue->Fetch()) {
            $coeff = $arProperty['VALUE'];

            $curElementRatio = MeasureRatioTable::getList([
                'filter' => [
                    '=PRODUCT_ID' => $arFields['ID'],
                ],
            ]);

            if ($arRatio = $curElementRatio->fetch()) {
                MeasureRatioTable::update($arRatio['ID'], [
                    'RATIO' => $coeff,
                ]);
            }
        }
    }
}

// Регистрируем обработчик события OnAfterIBlockElementAdd
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->registerEventHandler('iblock', 'OnAfterIBlockElementAdd', 'main', '', 'updateMeasureRatiosAfterElementChange');

// Регистрируем обработчик события OnAfterIBlockElementUpdate
$eventManager->registerEventHandler('iblock', 'OnAfterIBlockElementUpdate', 'main', '', 'updateMeasureRatiosAfterElementChange');

Этот код регистрирует обработчик событий для событий OnAfterIBlockElementAdd и OnAfterIBlockElementUpdate, который вызывает функцию updateMeasureRatiosAfterElementChange при добавлении или обновлении элемента инфоблока. Функция в свою очередь выполняет вашу логику обновления коэффициентов.

Обновление коэффициэнта из свойства при обмене с 1С

Вариант кода для init.php который будет срабатывать только при импорте товаров из 1С-Предприятие.

use Bitrix\Main\EventManager;
use Bitrix\Iblock\ElementTable;
use Bitrix\Catalog\MeasureRatioTable;

// Регистрируем обработчик события OnBeforeIBlockElementUpdate
EventManager::getInstance()->addEventHandler(
    'iblock',
    'OnBeforeIBlockElementUpdate',
    'DoUpdateElement'
);

// Регистрируем обработчик события OnBeforeIBlockElementAdd
EventManager::getInstance()->addEventHandler(
    'iblock',
    'OnBeforeIBlockElementAdd',
    'DoAddElement'
);

function DoUpdateElement(&$arFields)
{
    if ($_REQUEST['mode'] == 'import') {
        // Ваша логика по обработке данных перед обновлением элемента

        // Пример обновления коэффициентов
        updateMeasureRatios($arFields);
    }
}

function DoAddElement(&$arFields)
{
    if ($_REQUEST['mode'] == 'import') {
        // Ваша логика по обработке данных перед добавлением элемента

        // Пример обновления коэффициентов
        updateMeasureRatios($arFields);
    }
}

function updateMeasureRatios(&$arFields)
{
    // Проверяем, что существует свойство с нужным кодом
    if (isset($arFields['PROPERTY_VALUES']['KV_METROV_V_UPAKOVKE_CHIS'])) {
        $coeff = $arFields['PROPERTY_VALUES']['KV_METROV_V_UPAKOVKE_CHIS']['n0']['VALUE'];

        // Проверяем, что у элемента есть связь с коэффициентом
        $curElementRatio = MeasureRatioTable::getList([
            'filter' => [
                '=PRODUCT_ID' => $arFields['ID'],
            ],
        ]);

        if ($arRatio = $curElementRatio->fetch()) {
            MeasureRatioTable::update($arRatio['ID'], [
                'RATIO' => $coeff,
            ]);
        }
    }
}

Этот код предполагает, что коэффициент хранится в свойстве с кодом KV_METROV_V_UPAKOVKE_CHIS. Обработчики событий OnBeforeIBlockElementUpdate и OnBeforeIBlockElementAdd регистрируются для выполнения необходимых операций перед обновлением или добавлением элемента. Функция updateMeasureRatios обновляет коэффициент, если он присутствует.

Стоимость разработки на 1С-Битрикс:

Индивидуальная разработка магазина

от 400 000 руб. от 5-ти недель

Разработка магазина на 1С-Битрикс с нуля. Дизайн, сборка и оптимизация производительности под конкретный проект и требования. Реализация любого функционала без ограничений готовых решений.

Запуск сайта на готовом решении

от 100 000 руб. от 7-ми дней

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

Мобильное приложение

от 400 000 руб. от 1-го месяца

Разработка кроссплатформенного мобильного приложения, которое не уступает нативным решениям как в производительности, так и пользовательском опыте. Публикуется в AppStore, GooglePlay и RuStore

Сайт компании

от 250 000 руб. от 1-го месяца

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

Инфресурс

от 300 000 руб. от 5-ти недель

Информационный ресурс любой сложности. Сайт для СМИ, городской портал или многопользовательская доска объявлений. Внутренние форумы, блоги- по необходимости.

Лечение сайтов от вирусов

от 30 000 руб. от 2-х дней

Выполню полную проверку сайта и окружения. В случае обнаружения вирусов проведу полный комплекс лечения проекта и закрытия лазеек.