Diadoc¶
"Первая Форма" может получать документы, отправлять документы, подписывать или отклонять входящие документы (с указанием причины отказа) и отслеживать статус документов в системе электронного документооборота Диадок.
Для автоматизации используются очереди событий. За счет этого если какое-то действие не отработало с первого раза (например, сервис был временно недоступен), будут выполнены повторные попытки выполнить это действие.
У пользователей есть возможность подключения нескольких личных кабинетов Диадок, что может быть актуально для компаний с несколькими юридическими лицами, на каждое из которых оформляется отдельный личный кабинет. Это даёт возможность:
-
фиксировать юридическое лицо, от которого получены документы
-
отправлять статус документа в личный кабинет Диадок, соответствующий юр. лицу входящего документа
-
определять личный кабинет Диадок, соответствующий юридическому лицу исходящего документа
Акцептанту ЭДО не доступны для выбора сертификаты с истекшим или ещё не вступившим в действие сроком действия. Сертификаты в выпадающем списке располагаются по убыванию срока действия сертификата, срок действия отображается в скобках рядом с сертификатом.
В системе Диадок¶
Предоставьте учетной записи необходимые права:
На рабочем месте пользователя¶
Чтобы подписывать и отправлять электронные документы в системе Диадок необходимо использовать квалифицированную электронную подпись (КЭП). В Диадоке можно работать с различными СКЗИ, например с КриптоПро CSP.
-
плагин КриптоПро (ссылка на сайт КриптоПро). Не забудьте его включить!
-
КриптоПро CSP (ссылка на сайт КриптоПро)
Технические требования к рабочему месту
В «Первой Форме»¶
Действия для настройки интеграции:
-
Добавьте сервис с типом Diadoc.
-
Выберите его в качестве значения Diadoc service в общих настройках приложения.
-
Убедитесь, что задание SyncEdocumentsFromDiadocJob работает.
-
Убедитесь, что в очереди событий создан поток Edocument для обработки событий обмена данными с Диадоком (поток автоматически создается заданием).
-
Добавьте пользовательский ключ DiadocLastEventsId.
-
Автоматизируйте обработку событий, которые могут возникать при интеграции с Диадок:
-
Отправка документа в Диадок.
-
Изменение статуса документа в Диадоке.
-
Получение документа из Диадока.
Для автоматизации используйте:
| Системные события | Смарт-действия |
|---|---|
| ChangeEdocumentStatus — Изменился статус электронного документа в системе Диадок Изменение маршрута согласования. Событие ChangeEdocumentStatus отрабатывает также при снятии документа с маршрута согласования и постановке на другой маршрут в Диадоке. |
- Диадок — Отправить подписанное извещение о получении - Диадок — Отправить подписанный отказ от аннулирования - Диадок — Отправить подписанный отказ от подписи - Диадок — Отправить подписанный файл об аннулировании - Диадок — Отправить подписанный файл соглашения об аннулировании - Диадок — Отправить электронный документ - Диадок — Получить документ - Диадок — Получить идентификатор МЧД - Диадок — Получить контрагентов - Диадок — Получить статус МЧД - Диадок — Получить тэги документа - Диадок — Получить файлы МЧД - Диадок — Сгенерировать пустой xml титул покупателя для документа - Диадок — Сгенерировать xml титул для документа - Диадок — Синхронизировать статусы документов в сообщении - Диадок — Создать файл аннулирования подписи - Диадок — Создать файл извещения о получении - Диадок — Создать файл отказа от подписи - Диадок — Создать файл отклонения аннулирования подписи |
| ReceiveNewEdocument — Получен новый электронный документ через Диадок | LUA: SendEdocument, AttachSignature, AttachRejectionSignature, GenerateRejectionSignature, SaveEdocumentContentByLink, SaveEdocumentPrintFormByLink, SaveEdocumentArchiveFormByLink, AttachRevocationSignature, GenerateRevocationSignature, GenerateXmlBuyerTitle, GenerateXmlTitle, AttachTitleSignature, GetTagsFromDocument, SaveRevocationFile, AttachRevocationRequestedSignature, GenerateRejectRevocationSignature, AttachRevocationRejectionSignature, GenerateInvoiceReceiptXml, AttachInvoiceReceiptSignature, ReceiveMissedDocDiadoc, SyncMessageStatus, GetUserMCHDDiadoc, GetMCHDFilesDiadoc, GetCounteragents, GetMCHDStatusDiadoc, GetResolutionRoutes |
ℹ️ Если действие отправки в Диадок выполняется через смарт-скрипт (LUA), то параметр Signature в данном случае не является обязательным и используется только в том случае, если подпись серверная, а не запрошена в "Первой Форме"
ℹ️ В случае аннулирования резолюция требуется не для файла, полученного из системы Диадок, а для файла аннуляции.
Файл аннуляции сохраняется с помощью действия SaveRevocationFile, после чего либо отправляется подписанный файл об аннулировании (AttachRevocationRequestedSignature), либо создается файл отклонения аннулирования подписи (GenerateRejectRevocationSignature) и отправляется подписанный отказ от подписи (AttachRevocationRejectionSignature)
Логирование ответов¶
В "Первой Форме" есть возможность логировать ответы при интеграции с сервисом Диадок. По умолчанию логирование отключено. Для его включения необходимо добавить пользовательский ключ DiadocLogEnabled и установить его в значении true.
После включения в системе будут логироваться все события: их EventId, дата этого события (Timestamp), серверное время, MessageId документа, по которому пришло событие, EntityId этого документа, BoxId и ClientId ящика, по которому пришел этот документ. В том числе определяется новый ли это документ или происходит изменение уже существующего.
Записи в журнале не появляются, если при итерации заданий не было событий на обработку.
Отправка документа в Диадок¶
Пример: вы создали документ и вложили его в задачу или в ДП. Теперь нужно подписать его с помощью электронной подписи и отправить контрагенту через Диадок.
Подписание документа с помощью электронной подписи и отправка его контрагенту через Диадок инициируется внутри "Первой Формы", обычно при переходе по маршруту. Для запуска соответствующего действия используется привязка смарт-пакета к смарт-событию "После перехода".
Привязка действия¶
Привяжите действие к смарт-событию После перехода. В пакете достаточно настроить смарт-действие "Выполнить смарт-скрипт".
Скрипт для автоматизации¶
Скрипт удобнее писать на языке Lua, хотя те же действия можно реализовать с помощью смартов.
Пример Lua-скрипта для отправки файла в Диадок:
-- Получить ID файла из ДП с ID=99
local contractFileId = SQL:scalar([[
SELECT TOP 1 CONCAT(FileId, '.', VersionId)
FROM FileStorageFileToExtParamLinks
WHERE TaskID = @taskId AND ExtParamId = 99 AND IsDeleted = 0
]], {taskId = CONTEXT.Id});
-- получить ИНН (ДП с ID=22) и КПП (ДП с ID=33)
local customerInn = SQL:scalar([[
SELECT TOP 1 epv2.ExtParamValue
FROM ExtParamValues epv1
JOIN ExtParamValues epv2 ON epv2.TaskID = epv1.SelectedTaskId AND epv2.ExtParamId = 22
WHERE epv1.TaskID = @taskId AND epv1.ExtParamId = 11
]], {taskId = CONTEXT.Id});
local customerKpp = SQL:scalar([[
SELECT TOP 1 epv2.ExtParamValue
FROM ExtParamValues epv1
JOIN ExtParamValues epv2 ON epv2.TaskID = epv1.SelectedTaskId AND epv2.ExtParamId = 33
WHERE epv1.TaskID = @taskId AND epv1.ExtParamId = 11
]], {taskId = CONTEXT.Id});
RESULT = customerInn
-- Отправить файл в Диадок смарт-действием "Отправить электронный документ"
SMART:execute_action('SendEdocument', CONTEXT.Id, "task", {
File = contractFileId,
INN = customerInn,
KPP = customerKpp,
NeedReceipt = true,
EdocumentType = nil,
TotalSum = nil
})
RESULT = contractFileId
Изменение статуса документа в Диадок¶
Пример: вы создали документ, подписали его с помощью электронной подписи, вложили в задачу и отправили на подписание контрагенту через Диадок. Теперь нужно отследить изменение статуса документа в Диадоке: если контрагент подписал документ, задачу нужно перевести в статус Завершено, а если не подписал — в статус Отклонено.
Привязка действия¶
Для обработки внешнего события — изменения статуса документа в Диадоке — используйте очередь событий. Привяжите действие к системному событию ChangeEdocumentStatus. В пакете достаточно настроить смарт-действие "Выполнить смарт-скрипт".
Скрипт для автоматизации¶
Скрипт удобнее писать на языке Lua, хотя те же действия можно реализовать с помощью смартов.
Контекст события:
Для обработки поступающих событий в Lua можно использовать параметр CONTEXT, который содержит JSON вида:
{"inn":"...","created":"...","kpp":"...","type":"...","fileVersion":"...","id":"...","direction":"...","status":"...","field":"..."}
- inn — ИНН
- kpp — КПП
- created — дата создания
- type — тип документа в Диадоке. Возможные значения:
- Nonformalized — неформализованный документ (значение по умолчанию)
- Invoice — счет-фактура
- InvoiceRevision — исправление счета-фактуры
- InvoiceCorrection — корректировочный счет-фактура
- InvoiceCorrectionRevision — исправление корректировочного счета-фактуры
- TrustConnectionRequest — запрос на инициацию канала обмена документами через Диадок
- Torg12 — товарная накладная ТОРГ-12
- AcceptanceCertificate — акт о выполнении работ / оказании услуг
- ProformaInvoice — счет на оплату
- XmlTorg12 — товарная накладная ТОРГ-12 в XML-формате
- XmlAcceptanceCertificate — акт о выполнении работ / оказании услуг в XML-формате
- PriceList — ценовой лист
- PriceListAgreement — протокол согласования цены
- CertificateRegistry — реестр сертификатов
- ReconciliationAct — акт сверки
- Contract — договор
- Torg13 — накладная ТОРГ-13
- ServiceDetails — детализация
- SupplementaryAgreement — дополнительное соглашение к договору
- UniversalTransferDocument — универсальный передаточный документ (УПД)
- UniversalTransferDocumentRevision — исправление универсального передаточного документа
- UniversalCorrectionDocument — универсальный корректировочный документ (УКД)
- UniversalCorrectionDocumentRevision — исправление универсального корректировочного документа
- UnknownDocumentType — неизвестный тип документа; может выдаваться лишь в случае, когда клиент использует устаревшую версию SDK и не может интерпретировать тип документа, переданный сервером
- fileId — ID файла
- fileVersion — версия документа
- id — ID электронного документа
- direction — Inbound для входящих, Outbound для исходящих
- status — статус документа. Возможные значения:
- Unknown — по какой-то причине Диадок не может вернуть статус документа
- NotAcceptable — ответного действия не требуется. Либо это односторонний документ (например, счет, счет-фактура и УПД СЧФ), либо документ с опциональным запросом подписи, которая не была запрошена. Также сюда относится однотитульный акт (XmlAcceptanceCertificate)
- Waiting — ожидается ответное действие получателя документа. Если документ исходящий, то никаких действий не требуется; если входящий — нужно подписать документ или отклонить подпись
- Signed — получатель подписал документ
- Rejected — получатель отклонил подпись
- ResolutionRouteId — ID маршрута согласования в Диадоке (заполняется при получении документа, обновляется автоматически при смене/снятии маршрута через событие ChangeEdocumentStatus)
- ResolutionStatus — статус резолюции в Диадоке
- ResolutionIsFinished — признак завершённости согласования (true / false)
В скрипте нужно проверить сообщение, присылаемое Диадоком, и в зависимости от него перевести задачу в нужный статус.
Пример Lua-скрипта для события ChangeEdocumentStatus:
-- Меняем статус документа в зависимости от сообщения, полученного из Диадока
-- State = 3 — статус Завершено
-- State = 4 — статус Отклонено
-- InitUser = 3 и CommentAuthor = 3 — здесь 3 это ID пользователя Systemrobot
-- ищем номер задачи, в которой файл подписан с помощью ЭП
local taskId = SQL:scalar([[
SELECT TOP 1 TaskId
FROM
EdsFileInfo
WHERE SignedFileId = @fileId AND SignedFileVersionId = @fileVersion
]], {fileId = CONTEXT.FileId, fileVersion = CONTEXT.FileVersionId});
-- в зависимости от статуса, пришедшего из Диадока, меняем статус найденной задачи и пишем комментарий
if CONTEXT.Status == "Signed" then
SMART:execute_action('ChangeTaskStateForcibly', taskId, "task", { Task = taskId, InitUser = 3, State = 3, DoNotCheckRights = true, DoNotWriteComment = true, DoNotThrowErrors = true})
SMART:execute_action('PostComment', taskId, "task", { CommentAuthor = 3, CommentText = "Контрагент подписал документ.", Task = taskId, ForcedEmail = false, CommentSMS = false, NoSubscription = true, TextAsHTML = false})
elseif CONTEXT.Status == "Rejected" then
SMART:execute_action('ChangeTaskStateForcibly', taskId, "task", { Task = taskId, InitUser = 3, State = 4, DoNotCheckRights = true, DoNotWriteComment = true, DoNotThrowErrors = true})
SMART:execute_action('PostComment', taskId, "task", { CommentAuthor = 3, CommentText = "Контрагент отказал в подписи. Причина: '" .. CONTEXT.StatusMessage .. "'", Task = taskId, ForcedEmail = false, CommentSMS = false, NoSubscription = true, TextAsHTML = false})
end
RESULT = taskId
Получение документа из Диадок¶
Пример: контрагент прислал документ через Диадок. При получении документа возможны два варианта:
-
контрагент просто прислал вам документ без запроса подписи,
-
контрагент отправил вам документ на подпись. Вы должны обработать ее — подписать или отклонить.
Без запроса подписи¶
Если документ прислан без запроса подписи, достаточно сохранить присланный файл в файловое хранилище "Первой Формы", затем создать задачу и загрузить в нее этот файл из хранилища.
Пример Lua-скрипта для события ReceiveNewEdocument:
local userId = 3; -- ID пользователя Systemrobot
local subcatId = 123; -- ID категории, в которой регистрируются все входящие документы
local fileId = SMART:execute_action("SaveEdocumentContentByLink",1,"edocumentlink", { EdocumentLinkId = CONTEXT.Id})
local taskIds = SMART:execute_action("CreateTask",userId, "user", { Owner = userId, Subcat = subcatId, CreateLink = false, TaskText = "test", CreateSubtask = false, NewTaskCopySubscribers = false, CreateCopyFiles = false, CopyParentText = false, Priority = 1, CreateCopiesForEachPerformer = false })
SMART:execute_action("UploadFile",userId, "user", { Task = taskIds[0], UploadinUser = userId, File = fileId })
RESULT = fileId
С запросом подписи¶
Если документ прислан с запросом подписи, нужно выполнить следующие действия:
a) сохранить присланный файл в файловое хранилище "Первой Формы",
b) создать задачу и загрузить в нее этот файл из хранилища,
c) запросить подпись в задаче,
d) в зависимости от результата обработки подписи нужно отправить обратно в Диадок подписанный документ или файл отказа.
Пункты a и b соответствуют предыдущему разделу Без запроса подписи.
Для запроса подписи (пункт c) добавьте в тот же пакет действий смарт-действие "Выполнить переход по маршруту". На переходе должен быть настроен запрос подписи с включенным признаком ЭЦП.
Для обработки подписи (пункт d) настройте в категории две привязки:
- пакет действий к событию "После подписания статической подписи" - если подпись подписывается, нужно прикрепить к файлу ЭП. Тогда статус документа в Диадок изменится на "подписано"
Пример Lua-скрипта для прикрепления подписи:
-- Получить ID файла из ДП с ID=99
local contractFileId = SQL:scalar([[
SELECT TOP 1 CONCAT(FileId, '.', VersionId)
FROM FileStorageFileToExtParamLinks
WHERE TaskID = @taskId AND ExtParamId = 99 AND IsDeleted = 0
]], {taskId = CONTEXT.Id});
local fileSignedId = SMART:execute_action("AttachSignature",CONTEXT.Id,"task", { File = contractFileId });
RESULT = fileSignedId
- пакет действий к событию "После отклонения статической подписи" - если подпись отклоняется, нужно сгенерировать файл отказа
Пример Lua-скрипта для генерации файла отказа:
-- Получить ID файла из ДП с ID=99
local contractFileId = SQL:scalar([[
SELECT TOP 1 CONCAT(FileId, '.', VersionId)
FROM FileStorageFileToExtParamLinks
WHERE TaskID = @taskId AND ExtParamId = 99 AND IsDeleted = 0
]], {taskId = CONTEXT.Id});
local fileRejectionId = SMART:execute_action("GenerateRejectionSignature",CONTEXT.Id,"task", { File = contractFileId, Reason = "Причина отказа"});
local fileRejectionSignedId = SMART:execute_action("AttachRejectionSignature",CONTEXT.Id,"task", { File = contractFileId, RejectionFile = fileRejectionId});
RESULT = fileRejectionSignedId
Форматы документов¶
В Диадок поддерживаются следующие типы документов:
-
AcceptanceCertificate — акт о выполнении работ и оказании услуг (неформализованный),
-
ActOfsetting — акт на взаимозачёт,
-
AdjustmentOfClaim — корректировка претензии,
-
ApplicationForForwardingServices — заявка Т-ЭУ,
-
ApplicationForFunding — заявка в банк,
-
ApplicationForTransport — заявка на перевозку,
-
AttorneyLetterForGoodsAcceptance — доверенность на получение товаров,
-
BonusCertificate — акт премий,
-
CertificateRegistry — реестр сертификатов,
-
Claim — претензия,
-
Contract — договор,
-
ContractAppendix — приложение к договору,
-
CreditForm — кредитная анкета,
-
ElectricityIndication — показания электроэнергии,
-
ForwarderAssignment — поручение экспедитору,
-
ForwardingReceipt — экспедиторская расписка,
-
Invoice — счет-фактура,
-
InvoiceCorrection — корректировочный счет-фактура,
-
InvoiceCorrectionRevision — исправление корректировочного счета-фактуры,
-
InvoiceRevision — исправление счета-фактуры,
-
LeaveApplication — заявление на отпуск,
-
Letter — письмо,
-
LogisticsEpl — путевой лист,
-
LogisticsWaybill — титул транспортной накладной,
-
LogisticsWaybillDelivery — транспортная накладная о сдаче груза,
-
LogisticsWaybillForwarding — титул транспортной накладной,
-
LogisticsWaybillReception — транспортная накладная о приёме груза,
-
MesNotification — уведомление о переходе на ЭДО,
-
Nonformalized — неформализованный документ,
-
NotificationOfClaim — уведомление о претензии,
-
PerformedWorkAcceptanceCertificate — акт приемки выполненных работ КС-2,
-
PerformedWorkCostCertificate — справка о стоимости выполненных работ и затрат КС-3,
-
PowerOfAttorney — доверенность,
-
PriceList — ценовой лист,
-
PriceListAgreement — протокол согласования цены,
-
ProformaInvoice — счет на оплату,
-
ReconciliationAct — акт сверки,
-
ReportPrincipal — отчёт комитенту,
-
ResignationLetter — заявление на увольнение,
-
ReturnInventoryAcceptanceCertificate — акт МХ-3,
-
ServiceDetails — детализация,
-
SpotCheckAvailabilityCertificate — акт МХ-14,
-
StorageInventoryAcceptanceCertificate — акт МХ-1,
-
SupplementaryAgreement — дополнительное соглашение к договору,
-
Torg1 — акт о приемке товаров ТОРГ-1,
-
Torg2 — акт об установленном расхождении ТОРГ-2,
-
Torg12 — товарная накладная ТОРГ-12 (неформализованная),
-
Torg13 — накладная ТОРГ-13,
-
TrustConnectionRequest — запрос на инициацию канала обмена документами через Диадок,
-
UniversalCorrectionDocument — универсальный корректировочный документ,
-
UniversalCorrectionDocumentRevision — универсальный корректировочный документ (исправление),
-
UniversalTransferDocument — универсальный передаточный документ,
-
UniversalTransferDocumentAppendix — приложение к УПД,
-
UniversalTransferDocumentRevision — универсальный передаточный документ (исправление),
-
WaterConsumptionInformation — сведения о расходах воды,
-
Waybill — транспортная накладная,
-
WithdrawalOfClaim — отзыв претензии,
-
WorkOrder — заказ-наряд,
-
XmlAcceptanceCertificate — акт о выполнении работ и оказании услуг в XML-формате,
-
XmlTorg12 — товарная накладная ТОРГ-12 в XML-формате.
С форматами документов вы можете ознакомиться по ссылке.
Полезные ссылки¶
Использование JINT/SmartScript для кастомизации ЭДО¶
Начиная с версии 2.267 часть бизнес-логики интеграции с Диадок может быть реализована не только через встроенные C# смарт-действия, но и через системные библиотеки SmartScript на JavaScript (JINT).
Базовая библиотека eds-common подключается первой и предоставляет общие функции: HTTP-вызовы, SQL-хелперы, логирование, кэш токенов, загрузку файлов и работу с JSON. Для интеграции с Диадок дополнительно подключается библиотека diadoc-api.
Это позволяет вынести клиентскую бизнес-логику, маршрутизацию, обработку ответов API и сценарии обмена документами в SmartScript без доработки ядра и без новой сборки приложения.
Рекомендуемый шаблон подключения:
include("[edo] eds-common");
include("[edo] diadoc-api");
Новые сценарии рекомендуется писать на JavaScript. При этом прежние C#-смарт-действия сохраняют работоспособность и могут использоваться параллельно.
Для отладки JINT-сценариев следует использовать инфраструктуру логирования SmartScript.
В JINT-реализации основные операции выполняются синхронно и возвращают результат сразу в момент вызова скрипта, тогда как очередь сообщений используется главным образом для сценариев синхронизации статусов и входящих документов.