Как обработать входящий пакет документов
Для сокращения времени сотрудников, потраченного на создание и контроль первичной документации, в подключаемом модуле существуют следующие механизмы:
сопоставление полученных электронных документов с документами в базе 1С,
создание новых документов в 1С на основании полученных электронных документов,
дополнительный анализ входящих документов.
Сопоставление документов
Для типовых конфигураций предусмотрено сопоставление входящих электронных документов в формате xml, установленном ФНС, с типовыми документами 1С.
Например, входящий документ формата «УПД» сопоставляется с документом «Счет-фактура полученный», для которого существует документ-основание «Поступление товаров и услуг». Параметрами для сопоставления являются следующие поля документа 1С:
организация,
контрагент,
дата входящего документа,
номер входящего документа.
Описание правил сопоставления электронных документов, в зависимости от их типа, происходит в процедуре НайтиСопоставлениеДокумента.
Вызов события происходит при нажатии на кнопку «Сопоставить» в карточке входящего документа или кнопки «Сопоставить документ» в меню основной формы «Действия».
Пример сопоставления с документом типа «СчетФактураПолученный»:
Если СтруктураДанных.ТипДокумента = "Invoice"
ИЛИ (СтруктураДанных.ТипДокумента = "UniversalTransferDocument" И СтруктураДанных.ФункцияДокумента = "Invoice") Тогда
Результат = ПолучитьДокументы1С(ПараметрыОтбора, "СчетФактураПолученный");
КонецЕсли;
Правила ручного сопоставления документа
Автоматическое сопоставление может не определить подходящий документ. В этом случае поможет ручное сопоставление.
Для этого пользователь нажимает «Выбрать» в поле «Документ 1С», выбирает сначала тип, а затем и сам документ.
Для сокращения списка типов документов, которые подходят для сопоставления, используется событие ПравилаСопоставленияДокумента.
Кроме того, в этом методе задается фильтр на список документов. В типовом событии устанавливается отбор по организации и контрагенту.
Пример правила для сопоставления накладной:
Результат = Новый Структура;
РеквизитыДокумента = Параметры.РеквизитыДокумента;
ТипДокумента = РеквизитыДокумента.ТипДокумента;
ФункцияДокумента = РеквизитыДокумента.ФункцияДокумента;
Организация = РеквизитыДокумента.Организация;
Контрагент = РеквизитыДокумента.Контрагент;
ВозможныеВидыЭДО = ОсновнойМодуль.ЭДО_ВидыЭлектронныхДокументовПоФорматуЭДО(ТипДокумента, ФункцияДокумента);
ВидыЭДО = ОсновнойМодуль.ЭДО_Перечисление_ВидыЭДО();
Отбор = Новый Структура("Организация, Контрагент", Организация, Контрагент);
Для Каждого ВидЭДО Из ВозможныеВидыЭДО Цикл
Если ВидЭДО = ВидыЭДО.Накладная Тогда
ОсновнойМодуль.ЭДО_ДобавитьПравилоСопоставленияДокумента(Результат, "Документы", "ПоступлениеТоваровУслуг", Отбор);
ОсновнойМодуль.ЭДО_ДобавитьПравилоСопоставленияДокумента(Результат, "Документы", "ПоступлениеТоваровУслугВНТТ", Отбор);
ОсновнойМодуль.ЭДО_ДобавитьПравилоСопоставленияДокумента(Результат, "Документы", "ПоступлениеИзПереработки", Отбор);
ОсновнойМодуль.ЭДО_ДобавитьПравилоСопоставленияДокумента(Результат, "Документы", "ВозвратТоваровОтПокупателя", Отбор);
ОсновнойМодуль.ЭДО_ДобавитьПравилоСопоставленияДокумента(Результат, "Документы", "ПолучениеУслугПоПереработке", Отбор);
КонецЕсли;
КонецЦикла;
Возврат Результат;
Создание документов
Выбор вида документа
При нажатии на кнопку «Создать» из формы пакета пользователю предоставляется выбор - какой именно документ 1С создавать. Для управляемых форм есть предопределенный список видов документов, которые зависят от конфигурации. Список можно редактировать в событии СписокТиповДокументовДляСоздания.
Создание документа
Для возможности быстро формировать документы в 1С на основании полученного формализованного документа существует процедура ПолучитьЗаполненныйОбъектДокумента1С.
Полученные данные в формате XML преобразуются в XDTO структуру. Затем каждое поле в создаваемом документе 1С заполняется соответствующим реквизитом из получившейся струкутуры XDTO.
Вызов события происходит при нажатии на кнопку «Создать» в карточке входящего документа или кнопки «Создать документы» в меню основной формы «Действия в 1С».
Если СтруктураДанных.ТипДокумента = "XmlTorg12"
ИЛИ СтруктураДанных.ТипДокумента = "XmlAcceptanceCertificate"
ИЛИ (СтруктураДанных.ТипДокумента = "UniversalTransferDocument" И СтруктураДанных.ФункцияДокумента <> "Invoice")
ИЛИ (СтруктураДанных.ТипДокумента = "UniversalCorrectionDocument" И СтруктураДанных.ФункцияДокумента <> "Invoice") Тогда
ЭтоКорректировка = (СтруктураДанных.ТипДокумента = "UniversalCorrectionDocument");
ТекстXML = ОсновнойМодуль.ДвоичныеДанные_В_Текст(ОсновнойМодуль.ЭДО_ПолучитьХранилищеКонтента(ДокументДД));
ДеревоКонтента = ОсновнойМодуль.XML_В_XDTO(ТекстXML);
ТабличнаяЧасть = ОсновнойМодуль.ЭДО_ПолучитьТабличнуюЧастьИзКонтентаXML(ДеревоКонтента, ЭтоКорректировка);
Если СтруктураДанных.ТипДокумента = "UniversalCorrectionDocument" Тогда
СоздатьДокументКорректировки(ДокументДД, ПакетДД, СтруктураДанных, ТабличнаяЧасть, ДеревоКонтента, Результат);
Иначе
СоздатьДокументПоступления(ДокументДД, ПакетДД, СтруктураДанных, ТабличнаяЧасть, ДеревоКонтента, Результат);
КонецЕсли;
КонецЕсли;
Поиск документов, созданных на основании шаблона
Идентификаторы всех документов, созданных на основании шаблона, содержатся в коллекции Связи.TransformedToLetterIds структуры шаблона документа.
Эту коллекцию можно использовать для анализа в функции ПровестиАнализДокумента.
Документ = ОсновнойМодуль.Документы_СохраненныйДокумент(ДокументДД);
Шаблон = ОсновнойМодуль.Документы_ШаблонДокумента(Документ);
Если Не ЗначениеЗаполнено(Шаблон) Тогда
Возврат Результат;
КонецЕсли;
LetterId = Документ.Идентификаторы.LetterId;
DocumentId = Документ.Идентификаторы.DocumentId;
Документ1С = Неопределено;
ТекстОшибки = Неопределено;
КонтентОтвета = Неопределено;
ДокументУжеПолучен = Ложь;
Для каждого Элемент Из Шаблон.Связи.TransformedToLetterIds Цикл
Если Элемент.EntityId = DocumentId И Элемент.MessageId <> LetterId Тогда
ДокументУжеПолучен = Истина;
ТекстОшибки = НСтр("ru = 'Документ по шаблону уже получен'");
Прервать;
КонецЕсли;
КонецЦикла;
Если ДокументУжеПолучен Тогда
ДействиеВДД = "ОтказатьВПодписи";
КонтентОтвета = ПолучитьКонтентОтвета(ДокументДД, Документ1С, ДействиеВДД, ТекстОшибки);
Иначе
ДействиеВДД = "Подписать";
Документ1С = Шаблон.ДокументУчета;
КонтентОтвета = ПолучитьКонтентОтвета(ДокументДД, Документ1С, ДействиеВДД, ТекстОшибки);
КонецЕсли;
Если ЗначениеЗаполнено(ТекстОшибки) Тогда
Результат.Ошибки = Новый Массив;
Результат.Ошибки.Добавить(ТекстОшибки);
КонецЕсли;
Если ЗначениеЗаполнено(ДействиеВДД) Тогда
Результат.ДействиеВДД = ДействиеВДД;
КонецЕсли;
Если ЗначениеЗаполнено(Документ1С) Тогда
Результат.ДокументДляСопоставления = Документ1С;
КонецЕсли;
Если КонтентОтвета <> Неопределено Тогда
Результат.КонтентОтвета = КонтентОтвета;
КонецЕсли;
Сопоставление номенклатуры
При создании документа происходит поиск сопоставленной номенклатуры.
Если найти сопоставленную номенклатуру не удалось, то происходит ручное сопоставление с помощью таблицы значений.
Определение места хранения и правил заполнения происходит в функции СопоставитьНоменклатуруПоставщика.
ДлинаНаименования = Метаданные.Справочники.НоменклатураПоставщиков.ДлинаНаименования;
Для каждого СтрокаТЗ Из ТаблицаНоменклатурыДляСопоставления Цикл
НовыйОбъект = Справочники.НоменклатураПоставщиков.СоздатьЭлемент();
НовыйОбъект.Владелец = СтрокаТЗ.Контрагент;
НовыйОбъект.Наименование = Прав(СтрокаТЗ.Наименование, ДлинаНаименования); // Как правило окончание наименования является уникальным, поэтому пишем последние символы.
НовыйОбъект.Идентификатор = СтрокаТЗ.Код;
НовыйОбъект.Артикул = СтрокаТЗ.Артикул;
НовыйОбъект.Номенклатура = СтрокаТЗ.Номенклатура;
НовыйОбъект.Записать();
КонецЦикла;
Отбор сопоставления номенклатуры
При ручном сопоставление номенклатуры можно установить отбор.
Установка отборов происходит в функции ОтборСопоставленияНоменклатуры.
Типовыми полями отбора являются:
артикул,
код,
контрагент,
наименование,
ссылка на номенклатуру.
Результат = Новый Структура;
ПозицияНоменклатуры1 = Справочники.Номенклатура.НайтиПоНаименованию("Товар");
ПозицияНоменклатуры2 = Справочники.Номенклатура.НайтиПоНаименованию("Услуга");
МассивНоменклатур = Новый Массив;
МассивНоменклатур.Добавить(ПозицияНоменклатуры1);
МассивНоменклатур.Добавить(ПозицияНомеклатуры2);
Результат.Вставить("Ссылка", МассивНоменклатур);
Возврат Результат;
Анализ документов
Выполнение анализа вызывается нажатием на кнопку Анализ и обработка → Выполнить анализ.
В процедуре ПослеАнализаПакета выполняется логика обработки действий для каждого документа пакета.
Например, заполнение структуры ответа на входящий документ в зависимости от определенного действия (подписать, отказать в подписи и т.п.).
Для Каждого ТекДокумент Из ДокументыПакета Цикл
ДанныеДокумента = ТекДокумент.ДанныеДокумента;
ДокументДД = ТекДокумент.Ссылка;
Документ1С = ДанныеДокумента.ДокументВ1С;
ТекстОшибки = ДанныеДокумента.ТекстОшибки;
РезультатАнализа = ОсновнойМодуль.ЭДО_НовыйРезультатАнализаВходящегоДокумента();
СписокДействийТекДокумента = ОсновнойМодуль.ЭДО_ВариантыОтветныхДействийПоДокументу(ДокументДД, ОшибокНет);
РезультатАнализа.ДействиеВДД = ?(СписокДействийТекДокумента.Количество()=0, "", СписокДействийТекДокумента[0].Значение);
Если ЗначениеЗаполнено(РезультатАнализа.ДействиеВДД) Тогда
РезультатАнализа.Вставить("КонтентОтвета", ПолучитьКонтентОтвета(ДокументДД, Документ1С, РезультатАнализа.ДействиеВДД, ТекстВсехОшибокПакета));
КонецЕсли;
РезультатАнализа.Вставить("ДокументДляСопоставления", Документ1С);
ОсновнойМодуль.СохранитьРезультатАнализа(ДокументДД, РезультатАнализа);
КонецЦикла;
Завершающий этап анализа - выполнение определенных действий по подготовленным данным, определяется в процедуре ВыполнитьТребуемоеДействие.
Например, проводим документ 1С, если требуемое действие, сохраненное в 1С в документе подсистемы Диадока, называется «ПровестиДокумент».
ДокументДД = Параметры.ДокументДД;
ПакетДД = Параметры.ПакетДД;
ДанныеДокумента = ОсновнойМодуль.ЭДО_ПолучитьРеквизитыДокумента(ДокументДД);
Если ДанныеДокумента.ТребуемоеДействиеВ1С = "ПровестиДокумент" И ЗначениеЗаполнено(ДанныеДокумента.ДокументВ1С) Тогда
Документ1СОбъект = ДанныеДокумента.ДокументВ1С.ПолучитьОбъект();
Документ1СОбъект.Записать(РежимЗаписиДокумента.Проведение);
ОсновнойМодуль.ЭДО_ЗаписатьРеквизитыДокумента(ДокументДД, Новый Структура("ТребуемоеДействиеВ1С", "")); // отработали действие
КонецЕсли;