Если Ваш интернет-магазин интегрирован с 1С, скорее всего столкнулись с такой проблемой: 1С не умеет выгружать параметры товара: Вес, Ширина, Высота, Глубина.
Но эти параметры нужны для служб доставки, таких как Почта России, DHL и прочих. И желательно, что бы они были именно в параметрах товара модуля торгового каталога.
Заполнить их достаточно просто, для этого понадобиться создать дополнительные реквизиты в 1С с этими параметрами и воспользоваться методом API CCatalogProduct::Update
Заполняем параметры из свойств
Итак: мы создали доп реквизиты Вес, Ширина, Высота, Глубина в 1С, заполнили их и обменялись с сайтом. Теперь на сайте есть свойства ATT_WEIGHT, ATT_WIDTH, ATT_HEIGHT, ATT_LENGTH
Пишем простенький скрипт, который просто получит все элементы из инфоблока с каталогом (в примере, его ID = 15), с отбором данных свойств.
$addProps = CIBlockElement::GetList (
Array("ID" => "ASC"),
Array("IBLOCK_ID" => 15),
false,
false,
Array(
'ID',
'PROPERTY_ATT_WEIGHT',
'PROPERTY_ATT_WIDTH',
'PROPERTY_ATT_HEIGHT',
'PROPERTY_ATT_LENGTH'
)
);
while($ar_fields = $addProps->GetNext())
{
echo 'ID' . $ar_fields['ID'] .' / ';
echo 'Вес:' . $ar_fields['PROPERTY_WEIGHT_VALUE'].' / ';
echo 'Длина:' . $ar_fields['PROPERTY_DLINA_VALUE'].' / ';
echo 'Ширина:' . $ar_fields['PROPERTY_SHIRINA_VALUE'].' / ';
echo 'Высота:' . $ar_fields['PROPERTY_VYSOTA_VALUE'].'
';
}
endif;
Если запустить этот скрипт, просто получим вывод всех товаров каталога с указанием ID элемента и наших свойств.
Зная эти свойства, просто загоняем их значения в стандартные поля торгового каталога, методом CCatalogProduct::Update
$addProps = CIBlockElement::GetList (
Array("ID" => "ASC"),
Array("IBLOCK_ID" => 15),
false,
false,
Array(
'ID',
'PROPERTY_ATT_WEIGHT',
'PROPERTY_ATT_WIDTH',
'PROPERTY_ATT_HEIGHT',
'PROPERTY_ATT_LENGTH'
)
);
while($ar_fields = $addProps->GetNext())
{
echo 'Товару с ID-' . $ar_fields['ID'] .' установлены параметры';
echo 'Вес:' . $ar_fields['PROPERTY_ATT_WEIGHT_VALUE'].' / ';
echo 'Длина:' . $ar_fields['PROPERTY_ATT_WIDTH_VALUE'].' / ';
echo 'Ширина:' . $ar_fields['PROPERTY_ATT_HEIGH_VALUET'].' / ';
echo 'Высота:' . $ar_fields['PROPERTY_ATT_LENGTH_VALUE'];
Cmodule::IncludeModule('catalog');
$PRODUCT_ID = $ar_fields['ID'];
$arFields = array(
'WEIGHT' => $ar_fields['PROPERTY_ATT_WEIGHT_VALUE'],
'WIDTH' => $ar_fields['PROPERTY_ATT_WIDTH_VALUE'],
'HEIGHT' => $ar_fields['PROPERTY_ATT_HEIGHT_VALUE'],
'LENGTH' => $ar_fields['PROPERTY_ATT_LENGTH_VALUE']
);
CCatalogProduct::Update($PRODUCT_ID, $arFields);
}
endif;
В примере, вывод с небольшой свисто-перделкой- он выводит уведомление об установке параметров. Можно этого не делать, просто вывести echo 'Параметры успешно установлены';
Данный скрипт, подразумевает, что Вы будете запускать его в ручную, по необходимости. Это оптимально, если в каталоге не высокая текучка товаров и параметры товаров не меняются постоянно.
Само собой, можете добавить его в init.php дабы скрипт срабатывал на событиях
OnAfterIBlockElementUpdate - обновление элемента
OnAfterIBlockElementAdd - добавление элемента
Что повысит время обмена с 1С и в целом, нагрузку на сервер. Лучше повесить скрипт на агента, что бы срабатывал с некоторой переодичностью (раз в сутки, например). На врядли габариты товаров меняются постоянно и при каждом обмене.
Дополнение: Если 1С выгружает габариты в множественное свойство "Реквизиты"
Если ваша 1С выгружает габариты товаров в множественное свойство "Реквизиты" (пример на скрине):

Можно также получить данные цифры методом CIBlockElement::GetProperty а дальше заполнить штатные поля товара способом выше
Пример кода (в данном случае, нужно было еще и перевести сантиметры в миллиметры):
CModule::IncludeModule('iblock');
Cmodule::IncludeModule('catalog');
$iBlockID = 5; // ID инфоблока с товарами
$addProps = CIBlockElement::GetList(
Array("ID" => "ASC"),
Array("IBLOCK_ID" => $iBlockID),
false,
false,
Array(
'ID',
)
);
while ($ar_fields = $addProps->Fetch()) {
$VALUES = array(); // создаем пустой массив
$db_props = CIBlockElement::GetProperty(
$iBlockID,
$ar_fields['ID'],
array("sort" => "asc"),
Array("CODE" => "CML2_TRAITS") // код свойства с реквизитами
);
while ($ar_props = $db_props->Fetch()) {
$VALUES[] = $ar_props['VALUE']; // наполняем массив
}
$arFields = array(
// Берем габариты из значений массива (у вас могут быть другие номера
'WIDTH' => $VALUES['3'] * 10,
'HEIGHT' => $VALUES['4'] * 10,
'LENGTH' => $VALUES['5'] * 10;
);
CCatalogProduct::Update($ar_fields['ID'], $arFields);
echo "Габариты для " . $ar_fields['ID'] . " применены";
$arFields = array();
}
Небольшое пояснение к происходяему в скрипте:
- От метода CIBlockElement::GetList нам нужен только ID товара. Поэтому используем Fetch (работает быстрее).
- Методом CIBlockElement::GetProperty получили значения свойства CML2_TRAITS и наполниили ими массив $VALUES.
- В массив $arFields передали элементы массива $VALUES со значениями габаритов (рапечатайте print_r($VALUES), что бы увидеть свои).
- Массив $VALUES принудительно создается именно в нутри цикла, что бы очищался при каждой итерации
$arFields = array(
'WEIGHT' => $ar_fields['PROPERTY_ATT_WEIGHT_VALUE'],
'WIDTH' => $ar_fields['PROPERTY_ATT_WIDTH_VALUE'],
'HEIGH' => $ar_fields['PROPERTY_ATT_HEIGHT_VALUE'],
'LENGTH' => $ar_fields['PROPERTY_ATT_LENGTH_VALUE']

HEIGHT
Спасибо за статью.
OnAfterIBlockElementUpdate - обновление элемента
OnAfterIBlockElementAdd - добавление элемента
Будет не срабатывать запись, так как событие ProductUpdate срабатывает после и может перезаписывать свойство.
Тогда стоит попробовать поставить не на изменение элементов инфолока, а на изменение товара
Код |
---|
AddEventHandler("catalog", "OnBeforeOnBeforeProductUpdate", 'setDimensions'); |
Код |
---|
AddEventHandler("catalog", "OnBeforeProductAdd", 'setDimensions'); |
Полный пример кода который при изменениях в товаре или выгрузке 1С будет записывать габариты
Сайт по продаже шин, поэтому есть только объем, а для расчета отправки по почте нужны габариты
Код |
---|
AddEventHandler("catalog", "OnBeforeProductUpdate", 'setDimensions'); AddEventHandler("catalog", "OnBeforeProductAdd", 'setDimensions'); function setDimensions($id, &$arFields){ $addProps = CIBlockElement::GetList ( Array("ID" => "ASC"), Array("IBLOCK_ID" => array(17, 2), "ID" => $id), false, false, Array( 'ID', 'PROPERTY_SHIRINA_MM', 'PROPERTY_VYSOTA_MM', 'PROPERTY_OBEM', 'PROPERTY_VES' ) ); while($ar_fields = $addProps->GetNext()) { //Если есть параметры веса в свойствах инфоблока то ставим их if($ar_fields["PROPERTY_SHIRINA_MM_VALUE"] && $ar_fields["PROPERTY_VYSOTA_MM_VALUE"]){ $width = $ar_fields["PROPERTY_VYSOTA_MM_VALUE"]; $height = $ar_fields["PROPERTY_VYSOTA_MM_VALUE"]; $thickness = $ar_fields["PROPERTY_SHIRINA_MM_VALUE"]; //Если нету параметров но есть объем то высчитываем из объема примерные габариты }elseif ($ar_fields["PROPERTY_OBEM_VALUE"]){ $v = $ar_fields["PROPERTY_OBEM_VALUE"]; //Процентное соотношение габаритов относительно объёма 0.4*0.4*0.2/40% 40% 20% Высота Длина Ширина шины $r = pow($v/(0.4*0.4*0.2), 1/3); $width = round(0.4 * $r, 2)*1000; $height = round(0.4 * $r, 2)*1000; $thickness = round(0.2 * $r, 2)*1000; }else{ continue; } } $weight = $ar_fields["PROPERTY_VES_VALUE"] * 1000; $arFields["WEIGHT"] = $weight; $arFields["WIDTH"] = $width; $arFields["HEIGHT"] = $height; $arFields["LENGTH"] = $thickness; } |
Написал обработку для того что-бы из реквизитов товара брать вес и габариты торгового предложения.
Если интересно вот ссылка

Цитата |
---|
Борис Черепанов пишет: Добрый день Написал обработку для того что-бы из реквизитов товара брать вес и габариты торгового предложения. Если интересно [URL=https://xakplant.ru/2019/04/19/выгрузка-веса-высоты-ширины-длинны-из/]вот ссылка[/URL] |
Но пусть тоже будет, у меня чуть иначе сделано и без ТП
<?
function OnAfterIBlockElementUpdateAdd(&$arFields) {
$el = new CIBlockElement;
switch (SITE_ID ) {
case 's1':
$iBlockID = 12;
break;
case 's2':
$iBlockID = 49;
break;
}
$delivery_fields = array();
$db_props = CIBlockElement::GetProperty(
$iBlockID,
$arFields['ID'],
array("sort" => "asc"),
Array("CODE" => "CML2_TRAITS")
);
while ($ar_props = $db_props->Fetch()) {
switch ($ar_props["DESCRIPTION"]) {
case 'Длина':
$length = $ar_props['VALUE'];
break;
case 'Высота':
$height = $ar_props['VALUE'];
break;
case 'Ширина':
$width = $ar_props['VALUE'];
break;
}
}
$delivery_fields = array(
'LENGTH' => $length * 10,
'HEIGHT' => $height *10,
'WIDTH' => $width *10
);
\Bitrix\Catalog\Model\Product::update($arFields['ID'], $delivery_fields);
}
'HEIGHT' => $VALUES['4'] * 10,
'LENGTH' => $VALUES['5'] * 10;
Тут недочет - если из 1с не прийдет какое либо поле то ключи собьются и ваши габариты запишутся не туда, либо же к примеру прийдет еще 1поле - обьем, тогда
'WIDTH' => $VALUES['3'] * 10, уже будет не [3], а к [4] например, поэтому можно сравнивать по описанию полей
Тестил сегодня - все работает
Скрытый текст |
---|
<? function OnAfterIBlockElementUpdateAdd(&$arFields) { $el = new CIBlockElement; switch (SITE_ID ) { case 's1': $iBlockID = 12; break; case 's2': $iBlockID = 49; break; } $delivery_fields = array(); $db_props = CIBlockElement::GetProperty( $iBlockID, $arFields['ID'], array("sort" => "asc"), Array("CODE" => "CML2_TRAITS") ); while ($ar_props = $db_props->Fetch()) { switch ($ar_props["DESCRIPTION"]) { case 'Длина': $length = $ar_props['VALUE']; break; case 'Высота': $height = $ar_props['VALUE']; break; case 'Ширина': $width = $ar_props['VALUE']; break; } } $delivery_fields = array( 'LENGTH' => $length * 10, 'HEIGHT' => $height *10, 'WIDTH' => $width *10 ); \Bitrix\Catalog\Model\Product::update($arFields['ID'], $delivery_fields); } |
