Источник: http://dev.1c-bitrix.ru/community/webdev/user/173519/blog/8071/ |
Функция ВыгрузитьЗаказыВФайл(СтруктураИзменений, СтруктураПараметровСайта, Знач КаталогДляВыгрузки = "", //Меняем переменную КоличествоВыгруженныхЗаказов на КоличествоОбработанныхДокументовНаВыгрузке КоличествоОбработанныхДокументовНаВыгрузке = 0) Успешно = Истина; КоличествоВыгруженныхЗаказов = 0; МассивИзменений = Новый Массив; //Добавляем переменную МассивИзмененийКонтрагенты МассивИзмененийКонтрагенты = Новый Массив; //Формируем переменные ОбъектCMLСтрока и ОбъектCML. ОбъектCMLСтрока = ""; ДатаФормирования = ТекущаяДата(); ОбъектCML = ПолучитьОбъектДляЗаписиXML("", ДатаФормирования); Если ВыгружатьТолькоИзменения Тогда //Создаем переключатель Свитч = 0; МассивИзменений = СтруктураИзменений.Заказы; //Формируем МассивИзмененийКонтрагенты МассивИзмененийКонтрагенты = СтруктураИзменений.Контрагенты; // из этого массива нужно удалить все только что загруженные заказы Для Каждого Эл Из мМассивЗагруженныхДокументов Цикл ИндексЭлемента = МассивИзменений.Найти(Эл); Если ИндексЭлемента <> Неопределено Тогда МассивИзменений.Удалить(ИндексЭлемента); КонецЕсли; КонецЦикла; //Если нет изменений заказов Если МассивИзменений.Количество() = 0 Тогда // ТаблицаДокументов = ""; //Пишем КоличествоВыгруженныхЗаказов (оно равно 0) КоличествоВыгруженныхЗаказов = МассивИзменений.Количество(); //Пишем пользователю в 1с СообщитьПользователю("Изменения заказов не зарегистрированы. Выгрузка заказов не произведена.", Истина); Иначе //Пишем в переключатель единичку Свитч = 1; //Формируем заказы в xml (функцию СформироватьCMLСРанееЗагруженнымиЗаказами нужно немного переписать, код ниже) ТаблицаДокументов = СформироватьCMLСРанееЗагруженнымиЗаказами(ОбъектCML, МассивИзменений); //Считаем количество выгруженных заказов КоличествоВыгруженныхЗаказов = ТаблицаДокументов.Количество(); КонецЕсли; // Если нет изменений в контрагентах Если МассивИзмененийКонтрагенты.Количество() = 0 Тогда // ТаблицаДокументовКонтрагенты = ""; КоличествоВыгруженныхКонтрагентов = МассивИзмененийКонтрагенты.Количество(); СообщитьПользователю("Изменения контрагентов не зарегистрированы. Выгрузка контрагентов не произведена.", Истина); Иначе Свитч = 1; //Фомируем контрагентов, код функции ниже ТаблицаДокументовКонтрагенты = СформироватьCMLСКонтрагентами(ОбъектCML, МассивИзмененийКонтрагенты); КоличествоВыгруженныхКонтрагентов = ТаблицаДокументовКонтрагенты.Количество(); КонецЕсли; //Если выгружаем только изменения, а их нет, то возвращаем функцию Если Свитч = 0 Тогда Возврат Истина; КонецЕсли; //Если выгружаем все заказы и всех контрагентов без изменений Иначе ТаблицаДокументов = СформироватьCMLСРанееЗагруженнымиЗаказами(ОбъектCML, МассивИзменений); КоличествоВыгруженныхЗаказов = ТаблицаДокументов.Количество(); ТаблицаДокументовКонтрагенты = СформироватьCMLСКонтрагентами(ОбъектCML, МассивИзмененийКонтрагенты); КоличествоВыгруженныхКонтрагентов = ТаблицаДокументовКонтрагенты.Количество(); КонецЕсли; //Закрываем тэг в xml ОбъектCML.ЗаписатьКонецЭлемента(); //Пишем данные xml в ОбъектCMLСтрока ОбъектCMLСтрока = ОбъектCML.Закрыть(); //Смотрим есть ли выгруженные заказы или контрагенты Если КоличествоВыгруженныхЗаказов = 0 И КоличествоВыгруженныхКонтрагентов = 0 Тогда СообщитьПользователю("Не выгружен ни один заказ или контрагент.", Истина); Возврат Успешно; КонецЕсли; //Считаем количество ОбработанныхДокументов КоличествоОбработанныхДокументовНаВыгрузке = КоличествоВыгруженныхЗаказов + КоличествоВыгруженныхКонтрагентов; Если ПустаяСтрока(КаталогДляВыгрузки) Тогда Возврат Ложь; КонецЕсли; ИмяФайлаОбмена = "1cbitrix-" + Строка(Новый УникальныйИдентификатор) + ".xml"; ПолноеИмяФайлаОбмена = КаталогДляВыгрузки + "" + ИмяФайлаОбмена; СоздатьКаталог(КаталогДляВыгрузки); ФайлCMLНаДиске = Новый ТекстовыйДокумент; ФайлCMLНаДиске.УстановитьТекст(ОбъектCMLСтрока); Попытка ФайлCMLНаДиске.Записать(ПолноеИмяФайлаОбмена, "UTF-8"); Исключение СообщитьОбИсключительнойОшибке(Истина, "Не удалось записать CML файл на диск."); Возврат Ложь; КонецПопытки; //Добавляем выгруженно контрагентов в сообщение пользователю СообщитьПользователю("Выгружено заказов: " + КоличествоВыгруженныхЗаказов + " Выгружено контрагентов: " + КоличествоВыгруженныхКонтрагентов, Истина); Возврат Истина; КонецФункции |
Функция СформироватьCMLСРанееЗагруженнымиЗаказами(ОбъектCML, МассивИзменений) ОтобразитьСостояние("Поиск открытых заказов, загруженных с " + HTTPОбменСервер + "..."); ТаблицаДокументов = ПроцедурыОбменаССайтом.ПолучитьЗаказыСОплатойИОтгрузкойПоКатегориям(МассивИзменений, мМассивЗагруженныхДокументов); Если ТаблицаДокументов.Количество() = 0 Тогда Возврат ТаблицаДокументов; КонецЕсли; // ДатаФормирования = ТекущаяДата(); // ОбъектCML = ПолучитьОбъектДляЗаписиXML("", ДатаФормирования); Для Каждого СтрокаТД Из ТаблицаДокументов Цикл ОбъектCML.ЗаписатьНачалоЭлемента("Документ"); Док = СтрокаТД.ДокументСсылка; ВыгрузитьЗаказВCML(ОбъектCML, Док); ОбъектCML.ЗаписатьНачалоЭлемента("ЗначенияРеквизитов"); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Номер по 1С", Док.Номер); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Дата по 1С", ФорматДатыДляCML(Док.Дата)); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "ПометкаУдаления", Док.ПометкаУдаления); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Проведен", Док.Проведен); Если СтрокаТД.Оплачен ИЛИ СтрокаТД.Отгружен Тогда Если СтрокаТД.Оплачен Тогда ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Номер оплаты по 1С", СтрокаТД.НомерОплаты); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Дата оплаты по 1С", ФорматДатыДляCML(СтрокаТД.ДатаОплаты, Истина, Истина)); КонецЕсли; Если СтрокаТД.Отгружен Тогда ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Номер отгрузки по 1С", СтрокаТД.НомерОтгрузки); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Дата отгрузки по 1С", ФорматДатыДляCML(СтрокаТД.ДатаОтгрузки, Истина, Истина)); КонецЕсли; КонецЕсли; ОбъектCML.ЗаписатьКонецЭлемента(); ОбъектCML.ЗаписатьКонецЭлемента(); КонецЦикла; Возврат ТаблицаДокументов; КонецФункции |
Функция СформироватьCMLСКонтрагентами(ОбъектCML, МассивИзмененийКонтрагенты) ОтобразитьСостояние("Поиск контрагентов для выгрузки..."); //Процедура ПолучитьКонтрагентов описана ниже ТаблицаДокументовКонтрагенты = ПроцедурыОбменаССайтом.ПолучитьКонтрагентов(МассивИзмененийКонтрагенты); Если ТаблицаДокументовКонтрагенты.Количество() = 0 Тогда Возврат ТаблицаДокументовКонтрагенты; КонецЕсли; // Если МассивИзменений.Количество() = 0 Тогда // КонецЕсли; ОбъектCML.ЗаписатьНачалоЭлемента("Контрагенты"); Для Каждого СтрокаТД Из ТаблицаДокументовКонтрагенты Цикл ОбъектCML.ЗаписатьНачалоЭлемента("Контрагент"); ЗаписатьТекстовойУзел(ОбъектCML, "Код", СтрокаТД.Код); ЗаписатьТекстовойУзел(ОбъектCML, "Наименование", СтрокаТД.Наименование); ЗаписатьТекстовойУзел(ОбъектCML, "ИНН", СтрокаТД.ИНН); ЗаписатьТекстовойУзел(ОбъектCML, "ЮрФизЛицо", СтрокаТД.ЮрФизЛицоСсылка); ЗаписатьТекстовойУзел(ОбъектCML, "Адрес", СтрокаТД.ФактАдрес); ЗаписатьТекстовойУзел(ОбъектCML, "Телефон", СтрокаТД.Телефон); ЗаписатьТекстовойУзел(ОбъектCML, "Емэил", СтрокаТД.Емэил); // ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Наименование", СтрокаТД.Наименование); ОбъектCML.ЗаписатьКонецЭлемента(); КонецЦикла; // ОбъектCML.ЗаписатьКонецЭлемента(); ОбъектCML.ЗаписатьКонецЭлемента(); Возврат ТаблицаДокументовКонтрагенты; КонецФункции |
Функция ПолучитьКонтрагентов(МассивИзмененийКонтрагенты) Экспорт Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Контрагенты.Ссылка КАК Ссылка, | Контрагенты.Наименование КАК Наименование, | Контрагенты.ИНН КАК ИНН, | Контрагенты.ЮрФизЛицо.Ссылка КАК ЮрФизЛицоСсылка, | КонтактнаяИнформацияТелефон.Представление КАК Телефон, | КонтактнаяИнформацияАдрес.Представление КАК ФактАдрес, | КонтактнаяИнформацияЕмэил.Представление КАК Емэил, | Контрагенты.Код КАК Код |ИЗ | Справочник.Контрагенты КАК Контрагенты | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформацияТелефон | ПО Контрагенты.Ссылка = КонтактнаяИнформацияТелефон.Объект | И (КонтактнаяИнформацияТелефон.Тип = &ТипТелефон) | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформацияАдрес | ПО Контрагенты.Ссылка = КонтактнаяИнформацияАдрес.Объект | И (КонтактнаяИнформацияАдрес.Вид = &ВидФактАдрес) | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформацияЕмэил | ПО Контрагенты.Ссылка = КонтактнаяИнформацияЕмэил.Объект | И (КонтактнаяИнформацияЕмэил.Вид = &ВидЕмэил) |ГДЕ | Контрагенты.Ссылка В ИЕРАРХИИ(&СсылкаНаРодитель) | И (НЕ Контрагенты.Ссылка.ЭтоГруппа)"; //Я выбираю контрагентов только из раздела покупатели 1с, они имееют код 00015 Запрос.УстановитьПараметр("СсылкаНаРодитель", Справочники.Контрагенты.НайтиПоКоду("00015")); Запрос.УстановитьПараметр("ВидФактАдрес", Справочники.ВидыКонтактнойИнформации.НайтиПоКоду("2")); Запрос.УстановитьПараметр("ТипТелефон", Перечисления.ТипыКонтактнойИнформации.Телефон); Запрос.УстановитьПараметр("ВидЕмэил", Справочники.ВидыКонтактнойИнформации.НайтиПоКоду("000000013")); //Если в запросе присутствует массив изменений, то добавляем его в запрос Если МассивИзмененийКонтрагенты.Количество() > 0 Тогда Запрос.УстановитьПараметр("МассивДокументовСсылок", МассивИзмененийКонтрагенты); Запрос.Текст = Запрос.Текст + " И Контрагенты.Ссылка В (&МассивДокументовСсылок)"; КонецЕсли; ТаблицаДокументов = Запрос.Выполнить().Выгрузить(); Возврат ТаблицаДокументов; КонецФункции |
// Найти эти строчки в компоненте $objXML = new CDataXML(); $objXML->LoadString($sResult); $arResult = $objXML->GetArray(); // ЗДЕСЬ НАЧИНАЕТСЯ ИМПОРТ КОНТРАГЕНТОВ //Создадим переменный для подсчета $myContragentCount = 0; $myContragentSuccessAdd = 0; $myContragentSuccessUpdate = 0; $myImportLog= ''; //Для каждого контрагента из нашего xml foreach($arResult[GetMessage("CC_BSC1_COM_INFO")]["#"]["Контрагенты"][0]["#"]["Контрагент"] as $value) { //Если код или наименование пустое идем к следующему if(empty($value["#"]["Код"][0]["#"]) || empty($value["#"]["Наименование"][0]["#"])) { //Пишем в лог $myImportLog .= "Не заполнено поле наименование для контрагента с кодом: " . trim($value["#"]["Код"][0]["#"]) . "\n"; continue; } // Получаем индекс из адреса $userLocation = ''; $userIndex = preg_replace('/^(\d+).*$/', "$1", $value["#"]["Адрес"][0]["#"]); if(count($userIndex) > 0 && is_numeric($userIndex)) $userLocation = CSaleLocation::GetByZIP($userIndex); else $userIndex = ''; if(!empty($value["#"]["Емэил"][0]["#"])) { $userEmail = $value["#"]["Емэил"][0]["#"]; } else { //Если мэил не указан создаем из наимнования $userEmail = Cutil::translit($value["#"]["Наименование"][0]["#"], "ru", array("replace_space"=>"-","replace_other"=>"-")) . '@mail.you'; } $userName = substr($value["#"]["Наименование"][0]["#"], 0, 50); //Проверяем существует ли пользователь с XML_ID в базе битрикса $rsUser = CUser::GetList($by="", $order="", array("ACTIVE" => "Y", "XML_ID" => trim($value["#"]["Код"][0]["#"])), array("SELECT" => array("UF_*"))); if(!$arUser = $rsUser->Fetch()) { //если нет создаем нового пользователя $rand_password = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') , 0 , 10 ); $user = new CUser; $arFields = Array( // "NAME" => $userlogin, "NAME" => $userName, // "LAST_NAME" => "Иванов", "EMAIL" => $userEmail, "LOGIN" => trim($value["#"]["Код"][0]["#"]), "XML_ID" => trim($value["#"]["Код"][0]["#"]), "LID" => "s1", "ACTIVE" => "Y", "GROUP_ID" => array(2), "PASSWORD" => $rand_password, "CONFIRM_PASSWORD" => $rand_password, // Не пишет "ADMIN_NOTES" => $rand_password, "UF_TEMP_PASSWORD" => $rand_password, "WORK_COMPANY" => $value["#"]["Наименование"][0]["#"], ); $newUserID = $user->Add($arFields); if (!intval($newUserID) > 0) $myImportLog .= 'Не удалось создать пользователя с кодом: ' . $value["#"]["Код"][0]["#"] . "\n"; else { //выделяем тип пользователя из xml if(trim($value["#"]["ЮрФизЛицо"][0]["#"]) == 'Физ. лицо') $myPersonTypeId = 1; elseif(trim($value["#"]["ЮрФизЛицо"][0]["#"]) == 'Юр. лицо') $myPersonTypeId = 2; $arFields = array( "NAME" => $value["#"]["Наименование"][0]["#"], "USER_ID" => $newUserID, "PERSON_TYPE_ID" => $myPersonTypeId, ); $PROFILE_ID = CSaleOrderUserProps::Add($arFields); if ($PROFILE_ID) { //формируем массив свойств if($myPersonTypeId == 1) { $PROPS=Array( array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 20, "NAME" => "ИНН", "VALUE" => $value["#"]["ИНН"][0]["#"] ), array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 7, "NAME" => "Адрес доставки", "VALUE" => $value["#"]["Адрес"][0]["#"] ), array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 3, "NAME" => "Телефон", "VALUE" => $value["#"]["Телефон"][0]["#"] ), array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 6, "NAME" => "Местоположение", "VALUE" => $userLocation['ID'] ), array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 4, "NAME" => "Индекс", "VALUE" => $userIndex ) ); } elseif($myPersonTypeId == 2) { $PROPS=Array( array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 10, "NAME" => "ИНН", "VALUE" => $value["#"]["ИНН"][0]["#"] ), array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 19, "NAME" => "Адрес доставки", "VALUE" => $value["#"]["Адрес"][0]["#"] ), array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 14, "NAME" => "Телефон", "VALUE" => $value["#"]["Телефон"][0]["#"] ), array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 18, "NAME" => "Местоположение", "VALUE" => $userLocation['ID'] ), array( "USER_PROPS_ID" => $PROFILE_ID, "ORDER_PROPS_ID" => 16, "NAME" => "Индекс", "VALUE" => $userIndex ) ); } //добавляем значения свойств к созданному ранее профилю foreach ($PROPS as $prop) CSaleOrderUserPropsValue::Add($prop); $user = new CUser; if(!$user->Update($newUserID, array('UF_USER_PROPS_ID' => $PROFILE_ID))) $myImportLog .= 'Ошибка записи ID профиля покупателя в UF_USER_PROPS_ID: ' . $user->LAST_ERROR . "\n"; } else $myImportLog .= 'Ошибка создания профиля покупателя для контрагента: ' . $value["#"]["Наименование"][0]["#"] . "\n"; $myContragentSuccessAdd++; } } else { //Если пользователь существует обновляем $user = new CUser; $arFields = Array( // "NAME" => $userlogin, "NAME" => $userName, // "LAST_NAME" => "Иванов", "EMAIL" => $userEmail, "LOGIN" => trim($value["#"]["Код"][0]["#"]), "LID" => "s1", "ACTIVE" => "Y", // "GROUP_ID" => array(2), "WORK_COMPANY" => $value["#"]["Наименование"][0]["#"], ); if(!$user->Update($arUser['ID'], $arFields)) $myImportLog .= 'Ошибка обновления пользователя: ' . $user->LAST_ERROR . "\n"; else $myContragentSuccessUpdate++; // Обновляем данные профиля пользователя (ИНН, Адрес ...) $db_propVals = CSaleOrderUserPropsValue::GetList(($b="SORT"), ($o="ASC"), Array("USER_PROPS_ID"=>$arUser['UF_USER_PROPS_ID'])); while ($arPropVals = $db_propVals->Fetch()) { if($arPropVals['CODE'] == 'INN') { $arField = array( "USER_PROPS_ID" => $arPropVals['UF_USER_PROPS_ID'], "ORDER_PROPS_ID" => $arPropVals['ORDER_PROPS_ID'], "NAME" => "ИНН", "VALUE" => $value["#"]["ИНН"][0]["#"] ); CSaleOrderUserPropsValue::Update($arPropVals['ID'], $arField); } elseif($arPropVals['CODE'] == 'ADDRESS') { $arField = array( "USER_PROPS_ID" => $arPropVals['UF_USER_PROPS_ID'], "ORDER_PROPS_ID" => $arPropVals['ORDER_PROPS_ID'], "NAME" => "Адрес доставки", "VALUE" => $value["#"]["Адрес"][0]["#"] ); CSaleOrderUserPropsValue::Update($arPropVals['ID'], $arField); } elseif($arPropVals['CODE'] == 'PHONE') { $arField = array( "USER_PROPS_ID" => $arPropVals['UF_USER_PROPS_ID'], "ORDER_PROPS_ID" => $arPropVals['ORDER_PROPS_ID'], "NAME" => "Телефон", "VALUE" => $value["#"]["Телефон"][0]["#"] ); CSaleOrderUserPropsValue::Update($arPropVals['ID'], $arField); } elseif($arPropVals['CODE'] == 'ZIP') { $arField = array( "USER_PROPS_ID" => $arPropVals['UF_USER_PROPS_ID'], "ORDER_PROPS_ID" => $arPropVals['ORDER_PROPS_ID'], "NAME" => "Индекс", "VALUE" => $userIndex ); CSaleOrderUserPropsValue::Update($arPropVals['ID'], $arField); } elseif($arPropVals['CODE'] == 'LOCATION') { $arField = array( "USER_PROPS_ID" => $arPropVals['UF_USER_PROPS_ID'], "ORDER_PROPS_ID" => $arPropVals['ORDER_PROPS_ID'], "NAME" => "Местоположение", "VALUE" => $userLocation['ID'] ); CSaleOrderUserPropsValue::Update($arPropVals['ID'], $arField); } } } $myContragentCount++; } $myImportLog .= "\nСоздано пользователей в битриксе: " . $myContragentSuccessAdd; $myImportLog .= "\nОбновлено пользователей в битриксе: " . $myContragentSuccessUpdate; $myImportLog .= "\nВыгруженно контрагентов всего: " . $myContragentCount; //в корне сайта нужно создать файл bitrix_1c_import_log.txt, туда будет писаться лог file_put_contents( $_SERVER['DOCUMENT_ROOT'] . '/bitrix_1c_import_log.txt', $myImportLog); // КОНЕЦ ИМПОРТА КОНТРАГЕНТОВ |