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