Йо-йо! Сегодня я столкнулся с непростой и как мне кажется глупой задачей. Все кто давно работают с битриксом знают, что они постоянно продвигают торговые предложения. Однако в 1С это до сих пор «не завезли» и каждый пилит свои костыли.
Сегодня (19.04.2019) я сам столкнулся с тем, что мне не могли выгрузить вес, высоту, ширину, длину товара в параметры торгового каталога у торговых предложений и загружали их в реквизиты товара. Чтобы было понятно, что такое реквизиты, вот вам скриншот
И вот из этого места мне нужно положить в это
И всё это мне нужно, чтобы доставка у торговых предложений считалась корректно.
Я помыкался по форумам, вроде там кто-то что-то сделал, однако код не выложил. То что я нашёл на других сайтах мне не помогло. И без лишней лирики я покажу вам как решил данную задачу.
Это не очень простая задача. Сначала у меня не выходило получить все данные, которые мне были нужны, но я не понимал из-за чего. Потом на одном из форумов я увидел, что у человека уже была проблема похожая на мою и решение оказалось следующим:
Нужно поменять место хранения товаров и торговых предложений на «отдельная таблица» в настройках инфоблоков «Значения свойств хранятся:»
Далее по коду:
// Подключение модуля CModule::IncludeModule('iblock'); // Получение свойств товаров из инфоблока с ID 36, у меня это id каталога товаров $addProps = CIBlockElement::GetList ( Array("ID" => "ASC"), Array("IBLOCK_ID" => 36), false, false, Array( 'ID', 'PROPERTY_CML2_TRAITS' ) ); // Полученные свой перепаковываю while($ar_fields = $addProps->GetNext()) { // Получение свойств из реквизитов // Описание реквизитов, например, Ширина $arrDesc = $ar_fields['PROPERTY_CML2_TRAITS_DESCRIPTION']; // Значение $arrValue = $ar_fields['PROPERTY_CML2_TRAITS_VALUE']; $arrThmb = []; // Получение ассоциативного массива forEach($arrDesc as $key=>$value ){ $arrThmb[$value] = $arrValue[$key]; } // Получение конечного массива, без лишних свойств реквизитов $arrResult['ID'] = $ar_fields['ID']; $arrResult['Ширина'] = $arrThmb['Ширина']; $arrResult['Высота'] = $arrThmb['Высота']; $arrResult['Глубина'] = $arrThmb['Глубина']; $arrResult['Вес в упаковке'] = $arrThmb['Вес в упаковке']; }
Подключим ещё модуль каталога Cmodule::IncludeModule(‘catalog’) и получим id торговых предложений товара.
// Подключение модуля каталог Cmodule::IncludeModule('catalog'); CModule::IncludeModule('iblock'); $addProps = CIBlockElement::GetList ( Array("ID" => "ASC"), Array("IBLOCK_ID" => 36), false, false, Array( 'ID', 'PROPERTY_CML2_TRAITS' ) ); while($ar_fields = $addProps->GetNext()) { // print_r($ar_fields); // Получение свойств $arrDesc = $ar_fields['PROPERTY_CML2_TRAITS_DESCRIPTION']; $arrValue = $ar_fields['PROPERTY_CML2_TRAITS_VALUE']; $arrThmb = []; forEach($arrDesc as $key=>$value ){ $arrThmb[$value] = $arrValue[$key]; } $arrResult['ID'] = $ar_fields['ID']; $arrResult['Ширина'] = $arrThmb['Ширина']; $arrResult['Высота'] = $arrThmb['Высота']; $arrResult['Глубина'] = $arrThmb['Глубина']; $arrResult['Вес в упаковке'] = $arrThmb['Вес в упаковке']; // Получение торговых предложений $res = CCatalogSKU::getOffersList( $ar_fields['ID'], $iblockID = 0, $skuFilter = array(), $fields = array('ID'), $propertyFilter = array() ); // Массив по которому будем проходиться $arr = $res[$ar_fields['ID']]; }
Т.к. CCatalogSKU::getOffersList() возвращает данные для массива товаров, мы должны «перейти» на уровень глубже в массив. Для этого и нужна была строка $arr = $res[$ar_fields[‘ID’]];
Теперь нам нужно пройтись по массиву id-шников торговых предложений и изменить вес, ширину, высоту и длину у них. И сделаем мы это с помощью функции CCatalogProduct::Update($PRODUCT_ID, $arFields)
Cmodule::IncludeModule('catalog'); CModule::IncludeModule('iblock'); $addProps = CIBlockElement::GetList ( Array("ID" => "ASC"), Array("IBLOCK_ID" => 36), false, false, Array( 'ID', 'PROPERTY_CML2_TRAITS' ) ); while($ar_fields = $addProps->GetNext()) { // print_r($ar_fields); // Получение свойств $arrDesc = $ar_fields['PROPERTY_CML2_TRAITS_DESCRIPTION']; $arrValue = $ar_fields['PROPERTY_CML2_TRAITS_VALUE']; $arrThmb = []; forEach($arrDesc as $key=>$value ){ $arrThmb[$value] = $arrValue[$key]; } $arrResult['ID'] = $ar_fields['ID']; $arrResult['Ширина'] = $arrThmb['Ширина']; $arrResult['Высота'] = $arrThmb['Высота']; $arrResult['Глубина'] = $arrThmb['Глубина']; $arrResult['Вес в упаковке'] = $arrThmb['Вес в упаковке']; // Получение торговых предложений $res = CCatalogSKU::getOffersList( $ar_fields['ID'], $iblockID = 0, $skuFilter = array(), $fields = array('ID'), $propertyFilter = array() ); $arr = $res[$ar_fields['ID']]; // Изменение данных у торговых предложений forEach($arr as $key=>$value){ $PRODUCT_ID = $key; // id торгового предложения // Перечисление свойств $arFields = array( 'WEIGHT' => $arrResult['Вес в упаковке'], 'WIDTH' => $arrResult['Ширина'], 'LENGTH' => $arrResult['Глубина'], 'HEIGHT' => $arrResult['Высота'] ); CCatalogProduct::Update($PRODUCT_ID, $arFields); }; }
Т.к. перезапись нужна каждый раз когда выгружается товар из 1С, нам нужно поставить обработчик события. Для этого мы идём в наши файлы по адресу \bitrix\php_interface, находим там файлы init.php и пишем:
AddEventHandler("catalog", "OnSuccessCatalogImport1C", "myCustomImportMod"); function myCustomImportMod($arg1, $arg2 = false){ // Код, который был написан ранее }
Надеюсь, что данная статья будет вам полезной и вы быстро решите вашу задачу. Возможно вам нужно будет записать другие данные из реквизитов в торговый каталог, тогда вам понадобится список доступных параметров для изменения. Их вы можете найти тут. А если же вы не хотите самостоятельно заниматься разработкой, то можете написать мне в вк или телеграмм. Ссылки в подвале сайт.