При организации совместной работы старых конфигураций (например, 1С 7.7) и современных решений на базе 1С 8.3 (БП 3.0) часто возникает критическая проблема: документ, уже отправленный контрагенту через ЭДО Диадок, может быть случайно перезаписан при очередной синхронизации данных. Это приводит к расхождению данных в учетной системе и в электронном документе, что недопустимо с точки зрения налогового учета.
Для решения этой задачи нам необходимо научиться программно определять статус электронного документооборота для каждого конкретного документа и внедрять механизмы блокировки записи. Разберем по шагам, как это реализовано в различных вариантах поставки модуля Диадок и как правильно написать код защиты.
Если в вашей информационной базе Диадок установлен как расширение, это значительно упрощает задачу. Разработчики из Контура предусмотрели специальные метаданные для хранения связей. Проанализируем структуру хранения данных:
диадок_документы (или аналогичный с префиксом разработчика). В нем хранятся ссылки на объекты 1С и соответствующие им идентификаторы в системе Диадок.ДокументСсылка) соответствует нашему документу реализации или УПД.Диадок: Состояния документов. Это наиболее удобная точка входа. Если в этом регистре для конкретной ссылки на документ 1С существует запись, и ее состояние отличается от начального (например, статус "Отправлен", "Подписан" или "Доставлен"), значит, документ вовлечен в ЭДО.Рассмотрим пример функции, которую можно разместить в общем модуле для проверки блокировки:
Функция ДокументЗаблокированЭДО(ДокументСсылка) Экспорт
// Проверка для случая использования расширения
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Диадок_СостоянияДокументов.Состояние КАК Состояние
|ИЗ
| РегистрСведений.Диадок_СостоянияДокументов КАК Диадок_СостоянияДокументов
|ГДЕ
| Диадок_СостоянияДокументов.Объект = &ДокументСсылка";
Запрос.УстановитьПараметр("ДокументСсылка", ДокументСсылка);
Результат = Запрос.Выполнить();
Если НЕ Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Выборка.Следующий();
// Если статус не пустой и не "Не сформирован", блокируем
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Многие компании предпочитают не вносить изменения в структуру конфигурации и используют Диадок как внешнюю обработку. В этом случае модуль не может создавать свои справочники, поэтому он использует стандартный механизм 1С — Дополнительные сведения.
Выясним, как именно записываются эти данные. При отправке документа модуль создает запись в регистре сведений ДополнительныеСведения. В качестве объекта выступает ссылка на документ, а в качестве свойства — специально созданный дополнительный реквизит с именем ИдентификаторДокументаВДиадок (или аналогичным техническим именем DiadocMessageId).
Проанализируем алгоритм проверки для этого случая:
ДополнительныеСведения по паре "Объект" + "Свойство".Пример кода для проверки дополнительных сведений:
Функция ЕстьИдентификаторДиадок(СсылкаНаДокумент)
СвойствоИД = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ИдентификаторДокументаВДиадок");
Если СвойствоИД.Пустая() Тогда
Возврат Ложь;
КонецЕсли;
ЗначениеСведения = РегистрыСведений.ДополнительныеСведения.Получить(Новый Структура("Объект, Свойство", СсылкаНаДокумент, СвойствоИД)).Значение;
Возврат ЗначениеЗаполнено(ЗначениеСведения);
КонецФункции
Для более глубокой настройки можно изучить внутреннюю логику самой обработки Диадок. В макете КонтурДиадокИнтеграцияБП30 содержится текст запросов, которые модуль использует для формирования списков документов "К отправке".
Если мы проанализируем функцию ПолучитьТекстЗапросаДляСпискаПакетовНаОтправкуПоМассивуВидовПакетов(), то увидим, как разработчики Контура отфильтровывают уже отправленные документы. Обычно это делается через временную таблицу ВТ_ОтправленныеДокументы, которая собирает данные из вышеупомянутых регистров. Мы можем использовать аналогичную логику в своем коде проверки.
Чтобы защитить документ от изменений, которые приходят из 1С 7.7, недостаточно просто вывести предупреждение. Нужно внедрить проверку непосредственно в процесс записи объекта. Лучшим местом для этого является Подписка на событие ПередЗаписью.
Создадим подписку для документов РеализацияТоваровУслуг и СчетФактураВыданный. В обработчике события крайне важно учитывать флаг ОбменДанными.Загрузка. Рассмотрим, почему это важно.
Когда данные приходят из "семерки", платформа 1С устанавливает Загрузка = Истина. По умолчанию многие проверки в 1С в этом режиме отключаются. Нам же нужно, чтобы наша проверка на Диадок РАБОТАЛА даже при загрузке. Посмотрим на пример реализации обработчика:
Процедура ПередЗаписьюДокументаДляЭДО(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Если документ новый, проверять нечего
Если Источник.ЭтоНовый() Тогда
Возврат;
КонецЕсли;
// Проверяем наличие связи с Диадоком
Если ДокументЗаблокированЭДО(Источник.Ссылка) Тогда
// Если это интерактивное изменение пользователем
Если НЕ Источник.ОбменДанными.Загрузка Тогда
ТекстСообщения = "Документ уже отправлен через Диадок и заблокирован для редактирования!";
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения, Источник.Ссылка);
Отказ = Истина;
Иначе
// Если это загрузка из 1С 7.7
// Здесь мы можем либо вызвать Отказ = Истина (тогда обмен прервется с ошибкой)
// Либо просто проигнорировать изменения, не записывая их
ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Предупреждение,
Источник.Метаданные(), Источник.Ссылка, "Попытка изменения отправленного в Диадок документа проигнорирована.");
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Помимо программного запрета в БП 3.0, проанализируем ситуацию на стороне 1С 7.7 и в правилах конвертации. Чтобы избежать постоянных ошибок в логах обмена, рекомендуется внести изменения в правила выгрузки:
GetEntityContent) для оперативной проверки статуса документа напрямую на сервере Контура, если локальные регистры в 1С по какой-то причине не обновились.Таким образом, комбинируя поиск по служебным регистрам расширения и использование дополнительных сведений для внешних обработок, мы создаем надежный барьер, сохраняющий юридическую значимость наших электронных документов.