Вводная: Юристам требуется создавать договорные документы на основании заявки. Заявка это документы формата EXCEL и WORD. На её основании создают договорные документы, это документы в формате WORD. После создания документа, в процессе согласования есть вариант, что в заявку надо добавить пункты или изменить существующие(так что переформатировать в PDF не корректно для данного бизнес процесса), в следствии чего заявку редактируют. Далее заявка попадает к юристам, и они заново делают договор.
Условия
- Нельзя изменять бесконтрольно заявку на документ, только с согласия и уведомления Юристов
- Нельзя изменять бесконтрольно договорной документ созданный Юристами и находящийся на согласовании.
У данного решения есть два "но":
DocID = 390048
EDocument = EDocuments.GetObjectByID(DocID)
EDocLastVersionNum = GetLastEDocumentVersionNum(EDocument)
EDocVersions = EDocument.Versions
EDocLastVersion = EDocVersions.Values(EDocVersions.Count-1)
EDocLastVersion.lock // блокировка версии
EDocLastVersion.CreateClone(' Клонирование ';vsActive; false )
Из плюсов - версия документа раз подписана, становится невосприимчива к изменению. Из минусов - сертификаты надо обновлять.
Посмотрев оба решения и сделав их в коде, понял, что лучшее решение для меня это решение с ЭЦП. Самой большой трудностью стало то, что надо подписывать "тихо" и без участия пользователей. Подписывание происходит в блоке “Сценарий” в его вычислениях. То есть автор подписи становиться великий ISBuilderSystem. А тут неожиданный трабл возник –“Файл обмена личной информацией” с расширением *.pfx требуется разворачивать в профиле пользователя на компьютере. А такого места нет, даже на сервере, для данного пользователя.
Решение у меня не самое идеальное - это ключик в папке на сервере. Оттуда и забирает код через константу.
FreeException() // очистка исключений
ExceptionsOff() // защита от вылетов
DocID = 390048 // ид документа
EDocument = EDocuments.GetObjectByID(DocID)
EDocLastVersionNum = GetLastEDocumentVersionNum(EDocument)
EDocVersions = EDocument.Versions
Version = EDocVersions.Values(EDocVersions.Count-1) //получить версию документа которую надо подписать
// Найти подходящий сертификат
CertificateFound = False
CertificateForSignInfo = nil
//Получить список сертификатов
CurUserName = Application.Connection.UserName
JobPerformerUser = ServiceFactory.GetUserByName(CurUserName)
// JobPerformerUser = ServiceFactory.GetUserByID(104330) // конкретный исполнитель
CertificateList = ServiceFactory.GetUserECertificateList(JobPerformerUser)
//Получить первый сертификат
CertificateList.Reset
// Пока не достигнут конец списка сертификатов или сертификат не найден
stop = 0
колво = CertificateList.Count
if колво <100 and колво <<>>0
while not CertificateList.EOF
//Получить информацию о сертификате
CertificateForSignInfo = CertificateList.Value
имя = CertificateForSignInfo.Name
CertificateList.Next
stop = stop + 1
if stop ==20 // защита от вечного цикла
exit()
endif
endwhile
//Получить сертификат из БД из компоненты "Пользователи" (открытый ключ)
Certificate = CertificateForSignInfo.ECertificate
// Определить исполнителя задания
JobPerformerUser = ServiceFactory.GetUserByName("Administrator")
//Загрузить сертификат из личного хранилища
pass = '1'
Значение = Конст("pcSertIsBilder ") // путь сертификата
Certificate.Load(Значение;pass) // загрузить сертификат из файла
Certificate.Thumbprint = Certificate.Thumbprint
//Comment = time()&' Комментарий : Документ подписан автоматически в рамках задания с ИД: '& Object.ID
//stAuthenticating – визирующая подпись;
//stApproving – утверждающая подпись.
//Version.SignByAnotherUser(Certificate; JobPerformerUser; stAuthenticating; '' /*Comment*/) // подписания за кого
Version.Sign(Certificate; stAuthenticating; '' /*Comment*/) // автор сам подписывает
ExceptionsOn()
if ExceptionExists()
E = GetLastException()
Object.ActiveText = pProverka(E.Message)
endif
endif
P.S. Может кому-то поможет это (я потратил 3 дня на решения и отладку).
Добрый день, Юрий.
Достаточно много информации по вашей потребности содержится в материале FLY-DIRECTUM: часть 5. И верить в то, что не было измен. В тексте статьи рассмотрены различные варианты решения задачи и даны ссылки на описания других решений. Плюс достаточно оживлённая переписка в комментариях.
Два нюанса по вашим решениям:
1. Вы пишете "пользователь сразу увидит, что версия "в блоке", и сможет снять её".
Блокировку с версии может снять только тот, кто её поставил. Или администратор. Если мы блокируем версию документа от имени служебного пользователя, вероятность её непреднамеренного снятия будет стремиться к нулю.
2. Не совсем понятно, чем решение установки ЭП лучше решения установки блока в части "бардака в документах"? Необходимость создания новой версии возникает в обоих случаях.
Юрий, по опыту блокировки от системного пользователя вполне достаточно. Можно снимать блокировку когда документ разрешили редактировать. Вот тут есть технические нюансы блокировки, если надо.
Решение 1. "но" №3: при попытке переноса документа в архивное хранилище (по крайней мере в то, где запрещено редактирование) проверяется наличие блокировок самого документа и его версий. То есть, если служебные блокировки потом не снимать, может разрастись оперативное хранилище документов.
Решение 2. Чтобы не хранить закрытый ключ служебного пользователя в явном виде (хоть и на сервере) можете пересмотреть вопрос настройки самой системы: ввести служебного пользователя AD, настроив запуск служб под ним, и ему же устанавливать сертификаты (а также сможете выделить ему же служебный почтовый ящик, который сможете использовать для рассылки оповещений из системы и приёма обращений пользователей,...).
Авторизуйтесь, чтобы написать комментарий