Процедура ЮКОЗ_ЗагрузкаКП() Экспорт
//Инициализируем константные переменные
КаталогВрФл = КаталогВременныхФайлов();
ВидНоменклатуры = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ВидыНоменклатурыТовар");
ЕдиницаИзмШТ = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ЕдиницаИзмерения_ШТ");
ПриоритетСредний = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ПриоритетСредний");
СкладОсновной = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("СкладОсновной");
ТиповоеСоглашение = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ТиповоеСоглашение");
ВалютаДок = Константы.ВалютаРегламентированногоУчета.Получить();
АдресFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("АдресFTP");
ЛогинFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ЛогинFTP");
ПарольFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ПарольFTP");
//Соединямся с FTP-сервером и ищем необработанные файлы xml
ФТПСоединение = Новый FTPСоединение(АдресFTP,, ЛогинFTP, ПарольFTP,, Истина);
НайдемФайлаНаФТП = ФТПСоединение.НайтиФайлы("/", "*.xml");
//Если файлов нет, значит завершаем работу
Если НайдемФайлаНаФТП.Количество() = 0 Тогда
ФТПСоединение = Неопределено;
Возврат;
КонецЕсли;
//Подготавливаем таблицу значений для заполнения загружаемыми данными
ДанныеИзФайлаТовары = Новый ТаблицаЗначений();
ДанныеИзФайлаТовары.Колонки.Добавить("Артикул");
ДанныеИзФайлаТовары.Колонки.Добавить("ИД");
ДанныеИзФайлаТовары.Колонки.Добавить("Производитель");
ДанныеИзФайлаТовары.Колонки.Добавить("Номенклатура");
ДанныеИзФайлаТовары.Колонки.Добавить("Количество");
ДанныеИзФайлаТовары.Колонки.Добавить("Цена");
ДанныеИзФайлаТовары.Колонки.Добавить("Размер");
ДанныеИзФайлаТовары.Колонки.Добавить("Цвет");
ДанныеИзФайлаТовары.Колонки.Добавить("Серия");
ДанныеИзФайлаТовары.Колонки.Добавить("ЦенаСоСкидкой");
//Циклом обходим каждый найденный на FTP файл xml
Для каждого ФайлФТП из НайдемФайлаНаФТП Цикл
//Очищаем нашу таблицу значений, чтобы она могла хранить данные только по одному файлу xml
ДанныеИзФайлаТовары.Очистить();
//Получаем номер коммерческого предложения из имени файла xml
НомерКП = ФайлФТП.ИмяБезРасширения;
//Очищаем дату коммерческого предложения кототрую мы впоследствии возьмом из тела файла xml
ДатаКП = "";
//Обернём код в попытку, мало ли будут ошибки при загрузке и обработке файла
Попытка
//Загружаем файл на локальный компьютер
ПутьКФайлуОбъект = КаталогВрФл + ФайлФТП.Имя;
ФТПСоединение.Получить(ФайлФТП.ПолноеИмя, ПутьКФайлуОбъект);
//Перемещаем загруженный файл в директорию обработанных файлов на FTP
//Специально помещаем в начале, чтобы регламентное задание в случае ошибок в этом файле каждый раз не спотыкалось об него
ФТПСоединение.Переместить(ФайлФТП.ПолноеИмя, "OldFiles" + "\" + ФайлФТП.Имя);
//Инициализируем чтение файла xml
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуОбъект);
//Циклом обходим узлы XML файла и при совпадении с нужным именем узла записываем его значение в нашу таблицу значений
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда Продолжить; КонецЕсли;
ИмяУзла = ЧтениеXML.ЛокальноеИмя;
Если ИмяУзла = "PRODUCT" Тогда
НоваяСтрока = ДанныеИзФайлаТовары.Добавить();
Продолжить;
КонецЕсли;
Если ИмяУзла = "ID" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.ИД = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "ARTICLE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Артикул = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "SIZE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Размер = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "COLOR" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Цвет = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "NAME" И ЧтениеXML.КонтекстПространствИмен.Глубина = 5 Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Серия = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PROPERTY_PROVIDER_NAME" И ЧтениеXML.КонтекстПространствИмен.Глубина = 5 Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Производитель = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "NAME" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Номенклатура = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "QUANTITY" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Количество = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PRICE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Цена = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PRICE_DISCOUNT" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.ЦенаСоСкидкой = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "DATE" Тогда
ЧтениеXML.Прочитать();
ДатаСтр = СокрЛП(ЧтениеXML.Значение);
ДатаКП = Дата(ДатаСтр);
Продолжить;
КонецЕсли;
КонецЦикла;
//Закрываем чтение XML и удаляем ранее загруженный временный файл из нашего компьютера
ЧтениеXML.Закрыть();
УдалитьФайлы(ПутьКФайлуОбъект);
//Дата коммерческого предложения обязательно должна быть заполнена, если нет, то вызываем ошибку с пояснением для журнала регистрации
Если НЕ ЗначениеЗаполнено(ДатаКП) Тогда
ВызватьИсключение "Пустая дата по КП " + НомерКП;
КонецЕсли;
//Запросом найдем уже созданный ранее заказ клиента по загружаемому файлу
//Плохо, что запрос в цикле, но в данном случае можно ;) дабы не усложнять код.
ЗапросСущЗаказа = Новый Запрос();
ЗапросСущЗаказа.УстановитьПараметр("НомерКП", НомерКП);
ЗапросСущЗаказа.УстановитьПараметр("ДатаКП", НачалоДня(ДатаКП));
ЗапросСущЗаказа.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| ЗаказКлиента.Ссылка КАК Ссылка,
| ЗаказКлиента.Проведен КАК Проведен
|ИЗ
| Документ.ЗаказКлиента КАК ЗаказКлиента
|ГДЕ
| ЗаказКлиента.НомерПоДаннымКлиента = &НомерКП
| И ЗаказКлиента.ДатаПоДаннымКлиента = &ДатаКП";
Результат_ЗапросСущЗаказа = ЗапросСущЗаказа.Выполнить().Выбрать();
//Если заказ клиента найден и он проведен, то обновлять\изменять мы его уже не можем и вызываем ошибку с пояснением,
//если еще не проведен, то получаем ссылку на документ и работаем дальше
Если Результат_ЗапросСущЗаказа.Следующий() Тогда
Если Результат_ЗапросСущЗаказа.Проведен Тогда
ВызватьИсключение "Заказ уже проведен по КП " + НомерКП;
КонецЕсли;
ДокЗаказ = Результат_ЗапросСущЗаказа.Ссылка.ПолучитьОбъект();
//Если заказ клиента по загружаемому xml файлу еще не было, то создаем и заполняем его
Иначе
ДокЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
ДокЗаказ.Дата = ТекущаяДата();
ДокЗаказ.ЮКОЗ_НомерКПИзСайта = НомерКП;
ДокЗаказ.Приоритет = ПриоритетСредний;
ДокЗаказ.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.РеализацияКлиенту;
ДокЗаказ.ЦенаВключаетНДС = Истина;
ДокЗаказ.НалогообложениеНДС = Перечисления.ТипыНалогообложенияНДС.ПродажаОблагаетсяНДС;
ДокЗаказ.НомерПоДаннымКлиента = НомерКП;
ДокЗаказ.ДатаПоДаннымКлиента = ДатаКП;
ДокЗаказ.Склад = СкладОсновной;
ДокЗаказ.Статус = Перечисления.СтатусыЗаказовКлиентов.КОтгрузке;
ДокЗаказ.ЮКОЗ_Статус = Перечисления.ЮКОЗ_СтатусыЗаказовКлиентов.Согласование;
ДокЗаказ.Валюта = ВалютаДок;
ДокЗаказ.Соглашение = ТиповоеСоглашение;
ДокЗаказ.НеОтгружатьЧастями = Истина;
ДокЗаказ.ПорядокОплаты = Перечисления.ПорядокОплатыПоСоглашениям.РасчетыВВалютеОплатаВВалюте;
ДокЗаказ.ФормаОплаты = Перечисления.ФормыОплаты.Безналичная;
КонецЕсли;
//Очистим табличную часть Товары (на тот случай, если заказ клиента уже был ранее создан и там были какие-то данные)
ДокЗаказ.Товары.Очистить();
//Обходим данные из файла через нашу таблицу значений
Для каждого стр из ДанныеИзФайлаТовары Цикл
//Проверям на заполнение обязательный полей (артикул, производитель, номенклатура), если хоть что-то не заполнено, то вызываем ошибку с пояснением
Если НЕ ЗначениеЗаполнено(стр.Артикул) И НЕ ЗначениеЗаполнено(стр.ИД) Тогда
ВызватьИсключение "Пустой артикул и ID по КП " + НомерКП;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(стр.Производитель) Тогда
ВызватьИсключение "Пустой производитель по КП " + НомерКП;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(стр.Номенклатура) Тогда
ВызватьИсключение "Пустая номенклатура по КП " + НомерКП;
КонецЕсли;
//Пытаемся найти уже созданную номенклатуру по артикулу, а если он не заполнен, то по ИД.
ЗапросСущТовара = Новый Запрос();
ЗапросСущТовара.УстановитьПараметр("ИД", стр.ИД);
ЗапросСущТовара.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ" + Символы.ПС;
Если ЗначениеЗаполнено(стр.Артикул) Тогда
ЗапросСущТовара.Текст = ЗапросСущТовара.Текст + "Номенклатура.Артикул = &Артикул";
Иначе
ЗапросСущТовара.Текст = ЗапросСущТовара.Текст + "Номенклатура.ЮКОЗ_IDИзСайта = &ИД";
КонецЕсли;
Результат_ЗапросСущТовара = ЗапросСущТовара.Выполнить().Выбрать();
//Формируем представление строки описания номенклатуры (строковая характеристика)
ДобТоварЮКОЗ_Характеристика = ?(ЗначениеЗаполнено(стр.Серия), стр.Серия + ", ", "") +
?(ЗначениеЗаполнено(стр.Размер), стр.Размер + ", ", "") +
?(ЗначениеЗаполнено(стр.Цвет), стр.Цвет, "");
//Получаем ссылку на номенклатуру если она найдена
Если Результат_ЗапросСущТовара.Следующий() Тогда
ТоварСсылка = Результат_ЗапросСущТовара.Ссылка;
//Если номенклатура не найдена, то создаем её
Иначе
ТоварНовый = Справочники.Номенклатура.СоздатьЭлемент();
//Каждая номенлатура должна находится в своей группе в справочнике номенклатура, где название группы - это наименование производителя
//проверяем это запросом
ЗапросСущГруппы = Новый Запрос();
ЗапросСущГруппы.УстановитьПараметр("Производитель", стр.Производитель);
ЗапросСущГруппы.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование = &Производитель
| И Номенклатура.ЭтоГруппа";
Результат_ЗапросСущГруппы = ЗапросСущГруппы.Выполнить().Выбрать();
//Если группа найдено, то берем ссылку на неё
Если Результат_ЗапросСущГруппы.Следующий() Тогда
ГруппаТовараСсылка = Результат_ЗапросСущГруппы.Ссылка;
//Если группа не найдена, то создаем её
Иначе
ГруппаТовараСсылка = Справочники.Номенклатура.СоздатьГруппу();
ГруппаТовараСсылка.Наименование = стр.Производитель;
ГруппаТовараСсылка.Записать();
ГруппаТовараСсылка = ГруппаТовараСсылка.Ссылка;
КонецЕсли;
//Указываем, что номенклатуру мы создаем в группе которую нашли\создали чуть ранее
ТоварНовый.Родитель = ГруппаТовараСсылка;
//Формируем представление наименования номенклатуры, оно должно содержать артикул, а если его нет, то ИД
//Также записываем артикул, если его нет, то ИД вместо него.
Если ЗначениеЗаполнено(стр.Артикул) Тогда
ТоварНовый.Артикул = стр.Артикул;
ТоварНовый.Наименование = Строка(?(ЗначениеЗаполнено(стр.Артикул), "(" + стр.Артикул + ") ", "") + стр.Номенклатура);
Иначе
ТоварНовый.Наименование = Строка(?(ЗначениеЗаполнено(стр.ИД), "(" + стр.ИД + ") ", "") + стр.Номенклатура);
ТоварНовый.Артикул = стр.ИД;
КонецЕсли;
//Добавляем в наименование номенклатуры строковое описание номенклатуры, которое мы сформировали ранее,
//при условии, что описание номенклатуры есть и оно уже не встречается в наименовании номенклатуры
Если ЗначениеЗаполнено(ДобТоварЮКОЗ_Характеристика) Тогда
Если СтрНайти(СтрЗаменить(ТоварНовый.Наименование, ",", ""),
СтрЗаменить(ДобТоварЮКОЗ_Характеристика, ",", "")) = 0 Тогда
ТоварНовый.Наименование = ТоварНовый.Наименование + ", " + ДобТоварЮКОЗ_Характеристика;
КонецЕсли;
КонецЕсли;
//Заполняем остальные поля номенклатуры
ТоварНовый.ЮКОЗ_IDИзСайта = стр.ИД;
ТоварНовый.ТипНоменклатуры = Перечисления.ТипыНоменклатуры.Товар;
ТоварНовый.ВидНоменклатуры = ВидНоменклатуры;
ТоварНовый.НаименованиеПолное = стр.Номенклатура + ?(ЗначениеЗаполнено(ДобТоварЮКОЗ_Характеристика),
", " + ДобТоварЮКОЗ_Характеристика, "");
ТоварНовый.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
ТоварНовый.ЕдиницаИзмерения = ЕдиницаИзмШТ;
ТоварНовый.ЕдиницаДляОтчетов = ЕдиницаИзмШТ;
ТоварНовый.ИспользованиеХарактеристик = Перечисления.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать;
ТоварНовый.ВариантОформленияПродажи = Перечисления.ВариантыОформленияПродажи.РеализацияТоваровУслуг;
//Ищем производителя, если его нет, то создаем нового и указываем его в номенклатуре
ПроизводительСсылка = Справочники.Производители.НайтиПоНаименованию(стр.Производитель);
Если НЕ ЗначениеЗаполнено(ПроизводительСсылка) Тогда
НовыйПроизводитель = Справочники.Производители.СоздатьЭлемент();
НовыйПроизводитель.Наименование = стр.Производитель;
НовыйПроизводитель.Записать();
ПроизводительСсылка = НовыйПроизводитель.Ссылка;
КонецЕсли;
ТоварНовый.Производитель = ПроизводительСсылка;
//Записываем новую номенклатуру и получаем ссылку на неё
ТоварНовый.Записать();
ТоварСсылка = ТоварНовый.Ссылка;
КонецЕсли;
//Добавляем в табличную часть Товары номенклатуру с заполнением данных из файла xml
ДобТовар = ДокЗаказ.Товары.Добавить();
ДобТовар.Номенклатура = ТоварСсылка;
ДобТовар.Количество = стр.Количество;
ДобТовар.КоличествоУпаковок = стр.Количество;
ДобТовар.Упаковка = ДобТовар.Номенклатура.ЕдиницаИзмерения;
ДобТовар.Цена = стр.Цена;
ДобТовар.СтавкаНДС = ДобТовар.Номенклатура.СтавкаНДС;
ДобТовар.Склад = СкладОсновной;
ДобТовар.ЮКОЗ_Характеристика = ДобТоварЮКОЗ_Характеристика;
//Вычисляем процент ручной скидки, если в файле xml была указана цена со скидкой и она меньше, чем обычная цена
Если ЗначениеЗаполнено(стр.ЦенаСоСкидкой) И ЗначениеЗаполнено(стр.Цена) Тогда
стрЦенаСоСкидкой = Число(стр.ЦенаСоСкидкой);
стрЦена = Число(стр.Цена);
Если стрЦенаСоСкидкой > 0 И стрЦена > 0 И стрЦена > стрЦенаСоСкидкой Тогда
ДобТовар.ПроцентРучнойСкидки = (стрЦенаСоСкидкой / стрЦена - 1) * 100 * -1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Посчитаем сумму строки, а также НДС
СтруктураПересчетаСуммы = ОбработкаТабличнойЧастиКлиентСервер.ПараметрыПересчетаСуммыНДСВСтрокеТЧ(ДокЗаказ);
СтруктураДействий = Новый Структура;
СтруктураДействий.Вставить("ПересчитатьСумму", "КоличествоУпаковок");
СтруктураДействий.Вставить("ПересчитатьСуммуНДС", СтруктураПересчетаСуммы);
СтруктураДействий.Вставить("ПересчитатьСуммуСНДС", СтруктураПересчетаСуммы);
ОбработкаТабличнойЧастиСервер.ОбработатьТЧ(ДокЗаказ.Товары, СтруктураДействий, Неопределено);
//Запишем заказ клиента без проведения
ДокЗаказ.Записать(РежимЗаписиДокумента.Запись);
//Обработаем исключения в блоке попытки с записью в журнал регистрации для дальнейшего анализа
Исключение
ЗаписьЖурналаРегистрации("Ошибка обработки КП из сайта: " + ОписаниеОшибки(), УровеньЖурналаРегистрации.Ошибка);
КонецПопытки;
КонецЦикла;
//После обработки всех файлов, закроем FTP соединение.
ФТПСоединение = Неопределено;
КонецПроцедуры
{1} Высокая цикломатическая сложность: 35 {346} Переменной ФТПСоединение присвоено значение, но оно нигде не используется Орфографическая ошибка в Соединямся: Соединямся Орфографическая ошибка в кототрую: кототрую Орфографическая ошибка в возьмом: возьмом Орфографическая ошибка в Проверям: Проверям Орфографическая ошибка в номенлатура: номенлатура
Загрузка курсов валют с сайта РБК
ФоновоеЗаданиеЗагрузкиКлассификатораАдресовССайта (БСП)
Программная установка условного оформления (УО) поля динамического списка
НастройкиФорматовСохраненияТабличногоДокумента (БСП)
ПередСохранениемТабличногоДокументаВФормат (БСП)
ПриПодготовкеСпискаМакетовВФорматеОфисныхДокументовФормируемыхНаСервере (БСП)