// Диалог выбора штампа Res = InputDialogEx('*Вид:'; ; 'Pick:штамп регистрации документа,штамп электронной подписи:R'; 'Установка штампа на документ';;;;'ОК|Отмена';;'Отмена') if CharPos('Отмена'; Res) > 0 ShowMessage('Не выбран вид формируемого штампа документа!') Exit() endif DialogRes = SubString(Res; '|'; 1) // Штамп регистрации (дата и номер) //-------------------------- if DialogRes == 'штамп регистрации документа' RRC = Object DocumentID = RRC.ISBIntNumber RegNumber = RRC.Дополнение DateReg = RRC.ДатаВремя //Приводим в нужный вид данные о регистрации. //Можно удалить данный блок и дата и номер будут в полном формате Str = DateReg If Length(Str) > 10 Str = Copy(Str; 1; 10) DateReg = Str endif //Проверка на зарегистрированность документа If not Assigned(RegNumber) or not Assigned(DateReg) ShowMessage('РКК не зарегистрирована') exit() endif If not Assigned(DocumentID) ShowMessage('С РКК не связан основной документ') exit() endif //В зависимости от представления справочника меняем внешний вид проставляемого номера и даты If Object.ViewName == 'РККВх' HTML = ' Тег TABLE
'& DateReg &'
№ '& RegNumber &'
' endif if Object.ViewName == 'РККИсх' HTML = ' Тег TABLE
'& DateReg &' '& RegNumber &'
' endif if Object.ViewName == 'InnerRRC' HTML = ' Тег TABLE
'& DateReg &' '& RegNumber &'
' endif //Получаем документ Document = EDocuments.GetObjectByID(DocumentID) //Расширение имени файла CheckExtension = Document.Info.Editor.Extension // Преобразование в pdf If CheckExtension <<>> 'PDF' FCConvertEDocumentToPDF(Document) endif // Получить последнюю версию документа Version = GetLastEDocumentVersionNum(Document) Path = GetTempFolder() & "\" & "Stamp.png" HTMLFileName = Format("%s%s%s"; ArrayOf(GetTempFolder(); GetHashInFormatGUID(); '.html')) WriteFile(HTMLFileName;; HTML) GeneratePNGImageFromHTML(HTMLFileName; Path; TRUE) StampInsertComplit = FALSE StampAutoInsert = FALSE if InteractiveMode() while not StampInsertComplit Input = MessageBoxEx(INFORMATION_CAPTION; "Выберите действие";; "Сформировать|Сохранить|Отмена";;;; cbsCommandLinks; "Отмена") if Input == 'НЕУДАЧА: ESC' or Input == 'Отмена' Result = 'Прервано пользователем' exit() endif if Input == 'Сформировать' StampInsertComplit = FALSE //Задание координат по умолчанию If Object.ViewName == 'РККВх' InputSh = InputDialog('Отступ по горизонтали|Отступ по вертикали|Страница для штампа (0 - 1 стр.; 1 - послед.стр.)';'50|800|0';;;;;; TRUE) endif If Object.ViewName == 'InnerRRC' InputSh = InputDialog('Отступ по горизонтали|Отступ по вертикали|Страница для штампа (0 - 1 стр.; 1 - послед.стр.)';'135|180|0';;;;;; TRUE) endif If Object.ViewName == 'РККИсх' InputSh = InputDialog('Отступ по горизонтали|Отступ по вертикали|Страница для штампа (0 - 1 стр.; 1 - послед.стр.)';'70|300|0';;;;;; TRUE) endif //--------------------- STAMP_X = Substring(InputSh; "|"; 1) STAMP_Y = Substring(InputSh; "|"; 2) NumPage = Substring(InputSh; "|"; 3) FileName = GetTempFolder() & "\" & "\Temp.pdf" Document.Export(Version; FileName; False; False;;;) AddImage = AddImageToPDFFile(FileName; Path; STAMP_X; STAMP_Y; NumPage; ; 50) If AddImage OpenFile(FileName; 'N';'Да';ecotFile) else Showmessage("Штамп не установлен!") endif endif If Input == 'Сохранить' StampInsertComplit = TRUE DeleteFile(HTMLFileName) DeleteFile(Path) ImportFileIntoEDocumentVersion(FileName;;;;;Document.ID) ShowMessage('Штамп регистрации на документ успешно установлен!') endif endwhile endif Exit() endif //-------------------------- // Штамп регистрации (дата и номер) // Штамп электронной подписи //-------------------------- if DialogRes == 'штамп электронной подписи' // Определим текущего пользователя CurrentUser = EDocuments.CurrentUser // Проверить, есть ли основной документ MainDocumentID = Object.ISBIntNumber If Assigned(MainDocumentID) If not ExistLink(MainDocumentID; Object.SYSREQ_ID) Object.ПризнакНаличияНС3 = NO_VALUE Object.ISBIntNumber = '' MainDocumentID = '' endif else Result = 'С РКК не связан основной документ!' endif //Получим последнюю версию документа EDocument = EDocuments.GetObjectByID(MainDocumentID) VersionNumber = GetLastActiveEDocumentVersionNum(EDocument) //Присвоение номера последней активной версии CurrentVersion = EDocument.Versions.ValueByName(VersionNumber) // Проверка подписания документа ListECP = CurrentVersion.Signatures //Получить первую подпись ЭД ListECP.Reset foreach ECP in ListECP if Assigned(ECP.Author) CurrentUser = ECP.Author endif endforeach //Путь до временной папки TempFolder = GetTempFolder() //------------- //Инициализация переменных CertificateFound = False CertificateForSignInfo = nil //Тип подписи SignType = stApproving ShouldSignByAnotherUser = FALSE //Получить список сертификатов CertificateList = ServiceFactory.GetUserECertificateList(CurrentUser) //Получить первый сертификат CertificateList.Reset // Пока не достигнут конец списка сертификатов или сертификат не найден while not (CertificateList.EOF or CertificateFound) //Получить информацию о сертификате CertificateForSignInfo = CertificateList.Value CertificateFound = ((CertificateForSignInfo.CertificateType = ctSignature) or (CertificateForSignInfo.CertificateType = ctSignatureEncode)) and CertificateForSignInfo.IsDefault //Если сертификат не удовлетворяет условиям выше, присвоить переменной CertificateForSignInfo пустой указатель If not CertificateFound CertificateForSignInfo = nil endif //Перейти к следующему элементу списка сертификатов CertificateList.Next endwhile //Проверить на пустой указатель: если информация о сертификате не найдена, выдать сообщение пользователю Assert(not VarIsClear(CertificateForSignInfo); Format('У пользователя"%s" отсутствует сертификат для подписания'; CurrentUser.Name)) //Получить сертификат (открытый ключ) Certificate = CertificateForSignInfo.ECertificate //Получить права доступа пользователей к документу AccessRights = EDocument.AccessRights //Проверить права текущего пользователя на подписание ЭД if CurrentUser == EDocuments.CurrentUser AccessRights.CheckSign endif // Получить версию для подписания //Version = EDocument.Versions.Values(VersionNumber) //Получить список ЭЦП для ЭД. Если ЭД не подписан, список пуст ListECP=CurrentVersion.Signatures //Получить первую подпись ЭД ListECP.Reset //Проверить, может соответствующая версия уже подписана пользователем AlreadySign = FALSE foreach ECP in ListECP If not ShouldSignByAnotherUser If ECP.Author.ID = CurrentUser.ID and ECP.SignatureType = SignType AlreadySign = TRUE endif endif endforeach If Not AlreadySign Comment = "Signed!" //Загрузить сертификат из личного хранилища //Отпечаток сертификата Certificate.Thumbprint = Certificate.Thumbprint //Подписать версию ЭД CurrentVersion.Sign(Certificate; SignType; Comment) endif //Создание и экспорт штампа //Формирование штампа ЭП // Работаем с сертификатом //------------------ Result = CreateList() Signatures = CurrentVersion.Signatures // Проверить, есть ли ЭП на ЭД If Signatures.Count > 0 EDocID = CurrentVersion.Parent.ID EDocVersionID = sql("select XRecID from SBEDocVer where EDocID="& EDocID & " and Number="& CurrentVersion.Number) GetSignatureQueryTemplate = " select top 1 cast(cast(S.Sign as varbinary(max)) as varchar(max)) from SBEDocSignature S (nolock) where S.EDocID = %0:s and S.SignatureType = 'У' -- Утверждающая and isnull(S.ReplaceableUser, %1:s) = %1:s and S.VersionID=%2:s " GetSignatureQueryTemplate = " select cast(N'' as xml).value('xs:base64Binary(sql:column(''SignBin''))', 'varchar(max)') as SignB64 from (select top 1 cast(Sign as varbinary(max)) as SignBin from SBEDocSignature S (nolock) where S.EDocID = %0:s and S.SignatureType = 'У' -- Утверждающая and isnull(S.Author, %1:s) = %1:s --S.ReplaceableUser 27.03.2018 and S.VersionID=%2:s ) as xml " SignatureCount = 0 GerbFilePath = '' Certificate = nil foreach Signature in Signatures If Signature.SignatureType = stApproving Certificate = Signature.Certificate If Assigned(Certificate) SignerUserID = Signature.Author.ID // ByUser.ID // Выгрузить ЭП в файл напрямую из БД SignFileName = 'Sign' & EDocID & '_' & SignatureCount & '.p7s' SignFullFileName = GetTempFolder() & SignFileName GetSignatureQuery = Format(GetSignatureQueryTemplate; ArrayOf(EDocID; SignerUserID; EDocVersionID)) SQL("set quoted_identifier on set ansi_nulls on set concat_null_yields_null on SET ARITHABORT ON") SignatureBase64 = SQL(GetSignatureQuery) //вернет base64 SQL("set quoted_identifier off set ansi_nulls off set concat_null_yields_null off SET ARITHABORT OFF") SignatureBase64 = MimeDecodeString(SignatureBase64) WriteFile(SignFullFileName;; SignatureBase64) // Сгенерировать штамп отметки об ЭП на основе сертификата StampFullFileName = '' ExportStamps = 1 If ExportStamps StampFullFileName = PathForExport & '\Stamp' & EDocID & SignatureCount & '.png' SertNumber = Certificate.SerialNumber CAPICOMCertificate = CreateObject("CAPICOM.Certificate") CertPath = GetTempFolder() &'Cert.cer' // Экспортировать сертификат Certificate.Export(CertPath; ''; 1) // Загрузить сертификат в CAPICOM.Certificate CAPICOMCertificate.load(CertPath) SubjectNameList = CreateStringList() SubjectNameList.Delimiter = ',' // Получить строку с данными владельца сертификата SubjectNameList.DelimitedText = CAPICOMCertificate.SubjectName // Определить ФИО владльца сертификата Name = '' LastName = '' foreach SubjectNameListItem in SubjectNameList If CharPos('SN='; SubjectNameListItem) > 0 LastName = SubString(SubjectNameListItem; '='; 2) else If CharPos('G='; SubjectNameListItem) > 0 Name = SubString(SubjectNameListItem; '='; 2) endif endif endforeach FIO = LastName & ' ' & Name // Удалить выгруженный сертификат If FileExists(CertPath) DeleteFile(CertPath) endif Date = Format("с %0:s по %1:s"; ArrayOf(FormatDate("D.M.YY "; Certificate.ValidFromDate); FormatDate("D.M.YY "; Certificate.ValidToDate))) GenerateStateStamp(GerbFilePath; SertNumber; FIO; Date; StampFullFileName) If not FileExists(StampFullFileName) Raise(CreateException(''; 'Для генерации штампа подписи необходимо зарегистрировать библиотеку "GenerateTextImage". Обратитесь к администратору системы.'; ecWarning)) endif endif // Сформировать элемент результирующего списка с инфломацией о ЭП SignName = SignerUserID & '_' & Signature.SignatureType // ИД пользователя_Тип подписи Result.Add(SignName; ArrayOf(SignFullFileName; StampFullFileName)) SignatureCount = SignatureCount + 1 endif endif endforeach // if Signatures.Count > 0 endif //Получим результат т.е. массив ResFxValue = Result.Values(0) // ResFxValue = Res.Values(0) //Из массива получим 2 элемент PreviewPDFFilePath = ResFxValue[1] CheckExtension = EDocument.Info.Editor.Extension //Сконвертируем документ в PDF, если еще не сконвертирован If CheckExtension <<>> 'PDF' FCConvertEDocumentToPDF(EDocument) endif VersionNum = GetLastActiveEDocumentVersionNum(EDocument) StampInsertComplit = FALSE StampAutoInsert = FALSE If InteractiveMode() while not StampInsertComplit Input = MessageBoxEx(INFORMATION_CAPTION; "Выберите действие";; "Сформировать|Сохранить|Отмена";;;; cbsCommandLinks; "Отмена") If Input == 'НЕУДАЧА: ESC' or Input == 'Отмена' Result = 'Прервано пользователем' exit() endif If Input == 'Сформировать' StampInsertComplit = FALSE InputD = InputDialog('Отступ по горизонтали|Отступ по вертикали|Страница для штампа (0 - 1 стр.; 1 - послед.стр.; 2 - все стр.)';'330|650|0';;;;;; TRUE) X = Substring(InputD; "|"; 1) Y = Substring(InputD; "|"; 2) NumPage = Substring(InputD; "|"; 3) FileName = GetTempFolder() & '\Temp.pdf' EDocument.Export(VersionNum; FileName; False; False;;;) AddImage = AddImageToPDFFile(FileName; PreviewPDFFilePath; X; Y; NumPage; ; 50) If AddImage OpenFile(FileName; 'N';'Да';ecotFile) else showmessage("Штамп не установлен!") endif endif If Input == 'Сохранить' StampInsertComplit = TRUE ImportFileIntoEDocumentVersion(FileName;;;;;EDocument.ID) Showmessage("Документ подписан, штамп на документ установлен.") endif endwhile endif Exit() endif //-------------------------- // Штамп электронной подписи // Штамп основного документа на приложение //-------------------------- // Reserved //-------------------------- // Штамп основного документа на приложение