Телеграм: @camouf_ru Почта: mihail@bazarow.ru

Заполнение габаритов товара, после обмена с 1С, из свойств элемента инфоблока.

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

Если Ваш интернет-магазин интегрирован с 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 принудительно создается именно в нутри цикла, что бы очищался при каждой итерации
Denis Jutov 09.04.2019
Добрый день, тут в последнем пример кода есть опечатка,

$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

Спасибо за статью.
Denis Jutov 09.04.2019
Еще есть вариант того что при событиях
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;
}
Борис Черепанов 29.04.2019
Добрый день
Написал обработку для того что-бы из реквизитов товара брать вес и габариты торгового предложения.
Если интересно вот ссылка
Михаил Базаров 15.08.2020
Цитата
Борис Черепанов пишет:
Добрый день
Написал обработку для того что-бы из реквизитов товара брать вес и габариты торгового предложения.
Если интересно  [URL=https://xakplant.ru/2019/04/19/выгрузка-веса-высоты-ширины-длинны-из/]вот ссылка[/URL]
Не заметил это сообщение  :)  свое дописал сюда же.
Но пусть тоже будет, у меня чуть иначе сделано и без ТП
Сергей А 19.08.2022
Тестил сегодня - все работает


<?
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);
}
Сергей Антонов 19.08.2022
'WIDTH' => $VALUES['3'] * 10,
       'HEIGHT' => $VALUES['4'] * 10,
       'LENGTH' => $VALUES['5'] * 10;


Тут недочет - если из 1с не прийдет какое либо поле то ключи собьются и ваши габариты запишутся не туда, либо же к примеру прийдет еще 1поле - обьем, тогда
'WIDTH' => $VALUES['3'] * 10, уже будет не [3], а к [4] например, поэтому можно сравнивать по описанию полей

Тестил сегодня - все работает


Скрытый текст
Михаил Базаров 19.08.2022
В целом да. Если ключи собъются все поломается. Только и остается, проверять по точному названию поля.

Записная книжка разработчика

Примерно с 2013-го года пишу заметки по разработке сайтов на Битрикс.
Вы можете задавать уточняющие вопросы в комментариях- отвечаю или дополняю заметки по возможности.

Вывести новости из конкретного раздела инфоблока Битрикс Просмотров: 53465 Бывает что требуется вывести конкретные новости или статьи из одного раздела инфоблока в Б... Сгенерировать скидочные купоны, при заказе и отправить на почту Просмотров: 773 Задача: после того как пользователь сделал заказ, нужно сгенерировать одноразовые купоны д... Получение доступа к железу устройства из Битрикс мобильное приложение Просмотров: 5604 Документация к мобильному приложению 1С-Битрикс очень куцая. В основном описывает функцион... Звездочки в рейтинге Битрикс статей и новостей Просмотров: 18072 Стандартный вид рейтинга в новостях Битрикс, ну скажем так- не очень красив. Давайте его п... Малая корзина Битрикс, упрощенный шаблон Просмотров: 12545 Шаблон малой корзины битрикс, который можно вывести в боковом разделе шаблона или в шапке ... Регистрация пользователя в определенную группу сайта на Битрикс Просмотров: 22097 Достаточно часто требуется регистрировать пользователя в определенную группу, в зависимост... Открытие мобильного приложения Apache Cordova по ссылке Просмотров: 685 Достаточно часто нужно реализовывать открытие мобильного приложения по ссылке. Например: п... Создание мобильного приложения на cordova, для любого сайта. Просмотров: 14192 Если стоит задача разработки мобильного приложения для сайта, можете воспользоваться данно... Cordova, ввод в input под диктовку. Голосовой поиск в мобильном прило... Просмотров: 1264 Итак, задачка: реализовать голосовой поиск в мобильном приложении на Cordova. По сути, нам... Сниппеты типографики bootstrap, для Битрикс Просмотров: 7600 Если вы подключили bootstrap к своему сайту, или сверстали весь шаблон, подключив bootstra... Сортировка элементов по индексу сортировки значений типа список Просмотров: 10545 Внутри любого компонента есть заранее заложенные поля для сортировки элементов. МОжно сорт... Вывести свойство привязка к Яндекс Картам в Битрикс Просмотров: 18186 Часто бывает нужно вывести свойство привязка к Яндекс карте в детальном описании элемента... Показать пользователю накопительную скидку за все сделанные заказы, и... Просмотров: 1758 Задача: показать, текущему авторизованному, пользователю сумму всех выполненных заказов и ... Увеличение диска на готовой виртуальной машине Битрикс Просмотров: 8768 Как всем известно, на официальном сайте 1С-битрикс можно скачать готовую виртуальную машин... Умный фильтр во всплывающей панели на мобильных. Просмотров: 1449 Шаблон умного фильтра в Битриксе достаточно сложный, с точки зрения верстки и не очень кра... Как подобрать редакцию Битрикс под задачи Просмотров: 6350 Последнее время, все чаще, при общении с заказчиками, сталкиваюсь с вопросом "— К... Установка вебсервера на Apple M1 (нативный ARM стек), оптимизированны... Просмотров: 6143 Появилась задачка, установить стек MAMP (macOS, Apache, MYSQL, PHP) на рабочий ноутбук с п... Моментальная фильтрация на AJAX в умном фильтре 1С-Битрикс Просмотров: 24667 При штатной установке, интернет-магазина на 1С Битрикс, умный фильтр по товарам, показывае... Простой WEB сервер на ubuntu, для Битрикс Просмотров: 34480 Расскажу как по быстрому сконфигурировать WEB сервер для работы с Битрикс. Безо всяких ngi... Постраничная навигация в списке разделов Битрикс- catalog.section.lis... Просмотров: 8719 Если в магазине очень много разделов и хочется вывести их с постраничной навигацией: можно...