Как обработать входящий пакет документов

Для сокращения времени сотрудников, потраченного на создание и контроль первичной документации, в подключаемом модуле существуют следующие механизмы:

  • сопоставление полученных электронных документов с документами в базе 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С", "")); // отработали действие

КонецЕсли;