Сначала по основам.
1) При заполнении связанной с товаром таблицы b_catalog_product_sets, образуется связь один ко многим.
ссылка внутри битрикса
/bitrix/admin/perfmon_table.php?lang=ru&table_name=b_catalog_product_sets
ссылка описания в апи
https://bxapi.ru/src/?module_id=catalog&name=CCatalogProductSet::getAllSetsByProduct
Файл что бы копнуть d7
bitrix/modules/catalog/general/product_set.php
Также можно прочитать вот эту статью
https://dev.1c-bitrix.ru/community/webdev/user/173519/blog/20479/
а вот тут есть обработчик, но используется для торговых предложений
https://github.com/BedrosovaYulia/Sets-Import/blob/master/komplecty_import.php
Сразу замечу. Массив наборов добавляется пачкой. Обновляется так же. Все лишнее -удаляется. Нет никакого обновления по одному элементу набора. Исключительно пачкой все засовывается и обновляется. Смотрите табличку!!!!
. Делаем код )) Обрабатываем вот такой xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version="1.0" encoding="UTF-8"?> <Классификатор> <Набор> <ИД>96ded6ac-2710-11ea-8bd5-005056c00008</ИД> <Наименование>Ремкомплект стеклоподъемника 772430</Наименование> <СтрокаНоменклатуры> <Номенклатура> <ИД>96ded6aa-2710-11ea-8bd5-005056c00008</ИД> <Наименование>Комплект тросов стеклоподъёмника 772429</Наименование> </Номенклатура> </СтрокаНоменклатуры> <СтрокаНоменклатуры> <Номенклатура> <ИД>e5447baf-f190-11e9-a33e-005056a3e2a2</ИД> <Наименование>Ролик стеклоподъёмника 771576</Наименование> </Номенклатура> </СтрокаНоменклатуры> <СтрокаНоменклатуры> <Номенклатура> <ИД>96ded6a5-2710-11ea-8bd5-005056c00008</ИД> <Наименование>Направляющий держатель стеклоподъёмника 772424</Наименование> </Номенклатура> </СтрокаНоменклатуры> <СтрокаНоменклатуры> <Номенклатура> <ИД>96ded6a6-2710-11ea-8bd5-005056c00008</ИД> <Наименование>Направляющий держатель стеклоподъёмника 772425</Наименование> </Номенклатура> </СтрокаНоменклатуры> </Набор> .....Набор ...набор ... </Классификатор> |
ручной вызов обработчика
1 2 |
$arFields=$_SERVER["DOCUMENT_ROOT"].'/test/kits0_1.xml'; Provider1cFilter::loadXml1c($arFields); |
или же вызов из init.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
AddEventHandler('catalog', 'OnSuccessCatalogImport1C', 'customCatalogImportStep'); function customCatalogImportStep($arParams, $arFields) { file_put_contents($_SERVER["DOCUMENT_ROOT"]."/logsVash.txt", date("d-m-Y H:i:s")."; SESSION=".print_r($_SESSION,1)."; request ".print_r($_REQUEST,1)." pararm".print_r($arParams,1)." arFields ".print_r($arFields,1).";\n", FILE_APPEND); if (file_exists($arFields)) { //cстарый выгрузчик. // Provider1c::loadXml1c($arFields); Provider1cFilter::loadXml1c($arFields); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
<?php класс обработчика class Provider1CFilter { const IBLOCK_SPEC = 18; /** * * @param $url * @return mixed */ public static function getXml($url) { return json_decode(json_encode(simplexml_load_file($url)), true); } public static function WLog($str) { $date_str= date('Y-m-d H:i:s'); // echo $_SERVER["DOCUMENT_ROOT"]."/log.txt", $date_str."\n$str\n"; // file_put_contents($_SERVER["DOCUMENT_ROOT"]."/1c_log.txt", $date_str."\n$str\n", FILE_APPEND); } //получаем id - используется для комплекта public static function getIdByXML_ID($XML_ID){ $dbItems = \Bitrix\Iblock\ElementTable::getList(array( 'select' => array('ID', 'NAME', 'IBLOCK_ID', 'SORT', 'TAGS', 'XML_ID'), // выбираемые поля, без свойств. Свойства можно получать на старом ядре \CIBlockElement::getProperty 'filter' => array('XML_ID'=>$XML_ID ), // фильтр только по полям элемента, свойства (PROPERTY) использовать нельзя 'limit' => 1, // целое число, ограничение выбираемого кол-ва 'offset' => 0, // целое число, указывающее номер первого столбца в результате )); if($res=$dbItems->fetch()){ return $res['ID']; } else{ return false; } } //Id основного товара. айди, массив айди, с которых собираем цены public static function setPriceKomplekt($ID, $MASS_IDS){ //prr($ID); // prr($MASS_IDS); $PRICE_BY_GROUP=array(); $CURRENCY_BY_PRICE_BY_GROUP=array(); //собираем все цены в массив, ключом в котором CATALOG_GROUP_ID foreach ($MASS_IDS as $val) { $rsPrice = \Bitrix\Catalog\PriceTable::getList(array( 'filter'=>array('PRODUCT_ID'=>$val) )); while($arPrice=$rsPrice->fetch()) { $PRICE_BY_GROUP[$arPrice['CATALOG_GROUP_ID']][$arPrice['ID']]=$arPrice['PRICE']; $CURRENCY_BY_PRICE_BY_GROUP[$arPrice['CATALOG_GROUP_ID']]=$arPrice['CURRENCY']; } } // // prr($CURRENCY_BY_PRICE_BY_GROUP); foreach ($PRICE_BY_GROUP as $CATALOG_GROUP_ID=>$price_mass){ // prr($price_mass); $summ=0; foreach ($price_mass as $val){ $summ=$summ+$val; } $CURRENCY=$CURRENCY_BY_PRICE_BY_GROUP[$CATALOG_GROUP_ID]; /* echo $ID.'<br/>'; echo $CURRENCY.'<br/>'; echo $CATALOG_GROUP_ID.'<br/>'; echo $summ.'<br/>'; */ //выставляем цены и типы валюты $arFields = Array( "PRODUCT_ID" => $ID, "CATALOG_GROUP_ID" => $CATALOG_GROUP_ID, "PRICE" => $summ, "CURRENCY" => $CURRENCY, ); $res = CPrice::GetList( array(), array( "PRODUCT_ID" => $ID, "CATALOG_GROUP_ID" => $CATALOG_GROUP_ID ) ); if ($arr = $res->Fetch()) { CPrice::Update($arr["ID"], $arFields); } else { CPrice::Add($arFields); } } } public static function setKomplectByXML_ID($XML_ID, $MASS_KOMPLEKT){ $ID=Provider1CFilter::getIdByXML_ID($XML_ID); // prr($MASS_KOMPLEKT); // prr($XML_ID); $items=array(); $MASS_IDS=array();//массив Id для цен foreach ($MASS_KOMPLEKT as $val){ if($TEMP_ID=Provider1CFilter::getIdByXML_ID($val)){ // $MASS_ID_KOMPLEKT[]=$TEMP_ID; $MASS_IDS[]=$TEMP_ID; //формируем массив для выставления комплекта $items[]=array( 'ITEM_ID' => $TEMP_ID, 'QUANTITY' => 1, 'DISCOUNT_PERCENT' => 0, 'SORT' => 100, ); } } $arSetsByProduct = CCatalogProductSet::getAllSetsByProduct($ID, CCatalogProductSet::TYPE_SET); $arSetsByProduct = array_shift($arSetsByProduct); //Запись или апдейт комплекта if (!isset($arSetsByProduct)){ // echo 'создание'; $arSaveSet = array( 'TYPE' => 1, 'ITEM_ID' => $ID, 'ACTIVE' => "Y", 'ITEMS' => $items ); $setId = CCatalogProductSet::add($arSaveSet); // создание самого "комплекта" */ }else{ // echo 'update'; $arSaveSet = array( //'TYPE' => 1, //'ITEM_ID' => $arFields['ID'], //'ACTIVE' => "Y", 'ITEMS' => $items ); /* print "<pre>"; print_r(array($arSetsByProduct['SET_ID'],$arSaveSet)); print "</pre>"; die();*/ CCatalogProductSet::update($arSetsByProduct['SET_ID'],$arSaveSet); // апднйт "комплекта" CCatalogProductSet::recalculateSetsByProduct($ID); } // prr($ID); // prr($MASS_IDS); Provider1CFilter::setPriceKomplekt($ID, $MASS_IDS); } public static function loadKit($mass){ $count=0; //prr($mass); foreach ($mass as $key=>$item) { $XML_ID = $item['ИД']; $MASS2=array(); foreach ($item['СтрокаНоменклатуры'] as $kit) { $MASS2[]=$kit['Номенклатура']['ИД']; } // prr($MASS2); Provider1CFilter::setKomplectByXML_ID($XML_ID, $MASS2); $count++; if($count>=4){ // echo ' Ограничение !!!!!! Только 1 элемент'; // return; } } } public static function loadXml1c($url) { Cmodule::IncludeModule('catalog'); Cmodule::IncludeModule('iblock'); file_put_contents($_SERVER["DOCUMENT_ROOT"]."/1c_file.txt", date("d-m-Y H:i:s").";start file=".print_r($url,1).";\n", FILE_APPEND); require_once $_SERVER["DOCUMENT_ROOT"].'/local/filter/classes.php'; $result = self::getXml($url); \CModule::IncludeModule('iblock'); if (is_array($result)) { if(isset($result['Набор'])){ Provider1CFilter::WLog('start Набор '.$url); self::loadKit($result['Набор']); Provider1CFilter::WLog(' end Набор '.$url); } } file_put_contents($_SERVER["DOCUMENT_ROOT"]."/1c_file.txt", date("d-m-Y H:i:s").";end file=".print_r($url,1).";\n", FILE_APPEND); } } |
вот так подключили класс
1 2 3 4 5 |
\Bitrix\Main\Loader::registerAutoLoadClasses(null, [ 'Provider1cFilter' => '/local/filter/Provider1cFilter.php',//клас загрузки в табличку ]); |
А далее выжимка. Без доп функция, с забитыми вручную айдишиниками.
Добавление нового набора
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* Добавление $items=array(); $items[]=array( 'ITEM_ID' => 4074, 'QUANTITY' => 8, 'DISCOUNT_PERCENT' => 0, 'SORT' => 100, ); $arSaveSet = array( 'TYPE' => 1, 'ITEM_ID' => 6692, 'ACTIVE' => "Y", 'ITEMS' => $items ); $setId = CCatalogProductSet::add($arSaveSet); // создание самого "комплекта" */ |
Обновление
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$items[]=array( 'ITEM_ID' => 4074, 'QUANTITY' => 6, 'DISCOUNT_PERCENT' => 0, 'SORT' => 100, ); $items[]=array( 'ITEM_ID' => 5921, 'QUANTITY' => 4, 'DISCOUNT_PERCENT' => 0, 'SORT' => 100, ); $arSaveSet = array( 'ITEMS' => $items ); CCatalogProductSet::update(20,$arSaveSet); // апднйт элемента в комплекте!!! или что это за число 20 // //CCatalogProductSet::update($arSetsByProduct['SET_ID'],$arSaveSet); // апднйт "комплекта" CCatalogProductSet::recalculateSetsByProduct(6692); |