private Program(DiadocApi diadocApi, ICrypt crypt) { consoleContext = new ConsoleContext { DiadocApi = diadocApi, Crypt = crypt }; consoleCommands = new List <IConsoleCommand> { new AuthenticateCommand(consoleContext), new LoginCommand(consoleContext), new ListCounteragentsCommand(consoleContext), new ActOnCounteragentCommand(consoleContext), new SelectBoxCommand(consoleContext), new ListEventsCommand(consoleContext), new GetEventCommand(consoleContext), new GetMessageCommand(consoleContext), new PostMessageCommand(consoleContext), new PrintCommand(consoleContext), new ConfigureProxyCommand(consoleContext), new GetProxyStatusCommand(consoleContext), new SearchCommand(consoleContext), new GetInvoicesCommand(consoleContext), new AttorneyCommand(consoleContext), new StatusCommand(consoleContext), new ExitCommand(consoleContext) }; }
public void SetCurrentBoxWithOrgId(string orgId) { CurrentOrgId = orgId; var organization = DiadocApi.GetOrganizationById(orgId); CurrentBoxId = organization.Boxes[0].BoxIdGuid; }
public void SetCurrentBoxWithBoxId(string boxId) { CurrentBoxId = boxId; var organization = DiadocApi.GetOrganizationByBoxId(boxId); CurrentOrgId = organization.OrgId; }
public void Reload(string key = null) { IsLoading.Value = true; Observable.Start(() => { if (api == null) { api = new DiadocApi(Shell.Config.DiadokApiKey, Shell.Config.DiadokUrl, new WinApiCrypt()); } if (String.IsNullOrEmpty(token)) { token = api.Authenticate(Settings.Value.DiadokUsername, Settings.Value.DiadokPassword); box = api.GetMyOrganizations(token).Organizations[0].Boxes[0]; } var docs = api.GetDocuments(token, new DocumentsFilter { FilterCategory = "Any.Inbound", BoxId = box.BoxId, SortDirection = "Descending", AfterIndexKey = key }); var items = docs.Documents.Select(x => new { x.MessageId, x.EntityId }).Distinct() .AsParallel() .Select(x => api.GetMessage(token, box.BoxId, x.MessageId, x.EntityId)) .OrderByDescending(x => x.Timestamp) .ToObservableCollection(); return(Tuple.Create(items, $"Загружено {docs.Documents.Count} из {docs.TotalCount}", docs.Documents.LastOrDefault()?.IndexKey, api.GetMyOrganizations(token))); }, Scheduler) .ObserveOn(UiScheduler) .Do(_ => IsLoading.Value = false, _ => IsLoading.Value = false) .Subscribe(x => { SearchTerm.Value = ""; Total.Value = x.Item2; nextPage = x.Item3; if (!pageIndexes.Contains(nextPage)) { pageIndexes.Add(nextPage); } var display = new List <DisplayItem>(); Entity prev = null; foreach (var message in x.Item1) { foreach (var entity in message.Entities.Where(IsFile)) { display.Add(new DisplayItem(message, entity, prev, x.Item4)); prev = entity; } } orgs = x.Item4; items = display.ToObservableCollection(); Items.Value = display.ToObservableCollection(); }, e => { Log.Error("Не удалось загрузить документы диадок", e); Manager.Error(ErrorHelper.TranslateException(e) ?? "Не удалось выполнить операцию, попробуйте повторить позднее."); }); }
private static void Main(string[] args) { if (args.Length < 1) { ShowUsage(); return; } var apiClientId = args[0]; var apiUrl = args.Length > 1 ? args[1] : DefaultApiUrl; try { var crypt = new WinApiCrypt(); var diadoc = new DiadocApi(apiClientId, apiUrl, crypt); new Program(diadoc, crypt).Run(); } catch (Exception e) { System.Console.WriteLine(e); Environment.Exit(1); } }
public static void RunSample() { Console.WriteLine("Пример аутентификации по сертификату"); Console.WriteLine("====================================="); // Для использования API Диадока требуются: // 1. Крипто-API, предоставляемое операционной системой. Для систем на ОС Windows используйте класс WinApiCrypt. // 2. Экземпляр класса DiadocApi, проксирующий работу с Диадоком. var crypt = new WinApiCrypt(); var diadocApi = new DiadocApi( Constants.DefaultClientId, Constants.DefaultApiUrl, crypt); // Большинству команд интеграторского интерфейса требуется авторизация. // Для этого команды требуют в качестве обязательного параметра так называемый авторизационный токен — массив байтов, однозначно идентифицирующий пользователя. // Один из способов авторизации — через логин и пароль пользователя: var authTokenByLogin = diadocApi.Authenticate(Constants.DefaultLogin, Constants.DefaultPassword); Console.WriteLine("Успешная аутентификация по логину и паролю. Токен: " + authTokenByLogin); // Другой способ: через сертификат пользователя: var certificate = new X509Certificate2(File.ReadAllBytes(Constants.CertificatePath)); var authTokenByCertificate = diadocApi.Authenticate(certificate.RawData); Console.WriteLine("Успешная аутентификация по сертификату. Токен: " + authTokenByCertificate); // Можно использовать перегрузку, которая сама найдёт сертификат по отпечатку var authTokenByCertificateThumbprint = diadocApi.Authenticate(CertificateThumbprint); Console.WriteLine("Успешная аутентификация по отпечатку сертификата. Токен: " + authTokenByCertificateThumbprint); // В дальнейшем полученный токен следует подставлять в те методы API, где он требуется. (PostMessage и т.п.) // Токен длится 24 часа, после его протухания методы начнут возвращать 401, и потребуется вновь получить токен через методы выше. }
public static void PostLargeNonformalized() { // Для использования Диадок требуются: // 1. крипто-API, предоставляемое операционной системой (доступно через класс WinApiCrypt) // 2. экземпляр класса DiadocApi, проксирующий работу с веб-сервисом Диадок var crypt = new WinApiCrypt(); var api = new DiadocApi( DefaultClientId, // идентификатор клиента DefaultApiUrl, // URL веб-сервиса Диадок crypt); // Можно использовать либо аутентификацию по логину/паролю, либо по сертификату var authToken = api.Authenticate(DefaultLogin, DefaultPassword); // Для отправки комплекта документов через Диадок требуется подготовить структуру MessageToPost, // которая и будет содержать отправляемый комплект документов var message = new MessageToPost { // GUID ящика отправителя FromBoxId = DefaultFromBoxId, // GUID ящика получателя ToBoxId = DefaultToBoxId }; // Читаем содержимое отправляемого файла var content = ReadFileContent(FileToSendName); // Загружаем отправляемый файл на "полку" (на сервер временного хранения файлов Диадок) var uploadedFileShelfName = api.UploadFileToShelf(authToken, content); // Для того, чтобы подписать файл, требуется сертификат var certContent = ReadFileContent(FileWithCertName); var cert = new X509Certificate2(certContent); // Подписываем содержимое файла var signature = crypt.Sign(content, cert.RawData); // Формируем структуру для представления неформализованного (с точки зрения Диадока) документа var attachment = new NonformalizedAttachment { Comment = "Комментарий к отправляемому документу", // Комментарий к отправляемому документу FileName = new FileInfo(FileToSendName).Name, // Протокол обмена с Диадок требует наличия имени файла (без пути!) NeedRecipientSignature = false, // Требуется ли подпись получателя DocumentDate = DateTime.Now.ToShortDateString(), // Дата составления документа DocumentNumber = "123", // Номер документа CustomDocumentId = "", // Строковый идентификатор документа (если требуется связать документы в пакете) SignedContent = new SignedContent { NameOnShelf = uploadedFileShelfName, // Имя файла, ранее загруженного на "полку" Signature = signature // Подпись к отправляемому содержимому } }; // Документ подготовлен к отправке. Добавляем его в отправляемое сообщение message.AddAttachment(attachment); // Отправляем подготовленный комплект документов через Диадок var response = api.PostMessage(authToken, message); // При необходимости можно обработать ответ сервера (например, можно получить // и сохранить для последующей обработки идентификатор сообщения) Console.Out.WriteLine("Message was successfully sent."); Console.Out.WriteLine("The message ID is: " + response.MessageId); }
public static void RunSample() { Console.WriteLine("Пример отправки универсального передаточного документа (УПД) в формате приказа №820"); Console.WriteLine("==================================================================================="); // Для использования API Диадока требуются: // 1. Крипто-API, предоставляемое операционной системой. Для систем на ОС Windows используйте класс WinApiCrypt. // 2. Экземпляр класса DiadocApi, проксирующий работу с Диадоком. var crypt = new WinApiCrypt(); var diadocApi = new DiadocApi( Constants.DefaultClientId, Constants.DefaultApiUrl, crypt); // Авторизуемся в Диадоке. В этом примере используем авторизацию через логин-пароль: var authToken = diadocApi.Authenticate(Constants.DefaultLogin, Constants.DefaultPassword); // Также можно использовать авторизацию по сертификату, она описана в примере Authenticate.cs // Для отправки комплекта документов требуется подготовить структуру MessageToPost, // которая и будет содержать отправляемый комплект документов. // Для начала, укажем в структуре идентификаторы отправителя и получателя: var messageToPost = new MessageToPost { FromBoxId = Constants.DefaultFromBoxId, ToBoxId = Constants.DefaultToBoxId }; // Перечислим связку идентификаторов, которая характеризует полный формализованный тип документа в Диадоке var typeNamedId = "UniversalTransferDocument"; // строковый идентификатор типа УПД var function = "СЧФ"; // функция, представляющая УПД как счёт-фактуру var version = "utd820_05_01_01_hyphen"; // версия, отвечающая за то, что документ сформирован в формате приказа №820 // Теперь создадим сам формализованный документ. // Мы должны получить xml, которая будет удовлетворять его схеме: https://www.diadoc.ru/docs/laws/mmb-7-15-820 // C# SDK Диадока позволяет интеграторам создать объект типа UniversalTransferDocumentWithHyphens, // который получается из кодогенерации упрощенной xsd-схемы титула документа: var userDataContract = BuildUserDataContract(); // Теперь средствами универсального метода генерации мы получим из упрощенного xml // уже реальный титул документа, который будет удовлетворять приказу №820: Console.WriteLine("Генерируем титул отправителя..."); var generatedTitle = diadocApi.GenerateTitleXml( authToken, Constants.DefaultFromBoxId, typeNamedId, function, version, 0, userDataContract.SerializeToXml()); Console.WriteLine("Титул отправителя был успешно сгенерирован."); // Подпишем полученный титул через WinApiCrypt нашим сертификатом: Console.WriteLine("Создаём подпись..."); var content = generatedTitle.Content; var certificate = new X509Certificate2(File.ReadAllBytes(Constants.CertificatePath)); var signature = crypt.Sign(content, certificate.RawData); // здесь лежит бинарное представление подписи к УПД Console.WriteLine("Создана подпись к документу."); // Теперь передадим в структуру информацию о файле. // Для этого воспользуемся универсальным полем DocumentAttachment — через него можно отправить любой тип. var documentAttachment = new DocumentAttachment { /* * Чтобы Диадок знал, какой тип документа вы хотите отправить, * нужно заполнить поле TypeNamedId (а также Function и Version, если у типа больше одной функции и версии). * Узнать список доступных типов можно через метод-справочник GetDocumentTypes. * * Для наших целей (УПД с функцией СЧФ в формате приказа №820) мы уже подобрали нужную комбинацию выше: */ TypeNamedId = typeNamedId, Function = function, Version = version, // Теперь передадим сам файл УПД и сформированную к нему подпись: SignedContent = new SignedContent { Content = content, Signature = signature }, Comment = "Здесь можно указать любой текстовый комментарий, который нужно оставить к документу", CustomDocumentId = "Тут можно указать любой строковый идентификатор, например, для соответствия с вашей учётной системой", /* * У каждого типа документа в Диадоке может быть свой набор метаданных. * Их нужно указывать при отправке, если они обязательны. * Узнать набор требуемых метаданных для конкретного набора (тип-функция-версия-порядковый номер титула) * можно через тот же метод-справочник GetDocumentTypes: смотрите поля MetadataItems. * * Для формализованных документов метаданные обычно достаются из xml самим Диадоком. * Если у метаданных указан Source=Xml, отдельно передавать в MessageToPost их не нужно. */ }; // Добавим информацию о документе в MessageToPost: messageToPost.DocumentAttachments.Add(documentAttachment); // Наконец отправляем подготовленный комплект документов через Диадок Console.WriteLine("Отправляем пакет из одного УПД с функцией СЧФ..."); Console.WriteLine("Из ящика: " + messageToPost.FromBoxId); Console.WriteLine("В ящик: " + messageToPost.ToBoxId); var response = diadocApi.PostMessage(authToken, messageToPost); // При необходимости можно обработать ответ сервера (например, можно получить // и сохранить для последующей обработки идентификатор сообщения) Console.WriteLine("Документ был успешно загружен."); Console.WriteLine("MessageID: " + response.MessageId); Console.WriteLine("Количество сущностей в сообщении: " + response.Entities.Count); // В ответе будет две сущности, т.к. контент и подпись к нему хранятся отдельно друг от друга. // Выведем информацию о самом документе. Это можно сделать так: var responseDocument = response.Entities.FirstOrDefault(e => string.IsNullOrEmpty(e.ParentEntityId)); // т.к. у документа нет "родительских сущностей" Console.WriteLine("Идентификатор документа: " + responseDocument.EntityId); Console.WriteLine("Название документа: " + responseDocument.DocumentInfo.Title); }
public static void RunSample() { Console.WriteLine("Пример отправки неформализованного документа"); Console.WriteLine("============================================"); // Для использования API Диадока требуются: // 1. Крипто-API, предоставляемое операционной системой. Для систем на ОС Windows используйте класс WinApiCrypt. // 2. Экземпляр класса DiadocApi, проксирующий работу с Диадоком. var crypt = new WinApiCrypt(); var diadocApi = new DiadocApi( Constants.DefaultClientId, Constants.DefaultApiUrl, crypt); // Авторизуемся в Диадоке. В этом примере используем авторизацию через логин-пароль: var authToken = diadocApi.Authenticate(Constants.DefaultLogin, Constants.DefaultPassword); // Также можно использовать авторизацию по сертификату, она описана в примере Authenticate.cs // Для отправки комплекта документов требуется подготовить структуру MessageToPost, // которая и будет содержать отправляемый комплект документов. // Для начала, укажем в структуре идентификаторы отправителя и получателя: var messageToPost = new MessageToPost { FromBoxId = Constants.DefaultFromBoxId, ToBoxId = Constants.DefaultToBoxId }; // Подготовим контент и подпишем его через WinApiCrypt нашим сертификатом: var content = File.ReadAllBytes(NonformalizedDocumentPath); // здесь лежит бинарное представление неформализованного документа Console.WriteLine("Создаём подпись..."); var certificate = new X509Certificate2(File.ReadAllBytes(Constants.CertificatePath)); var signature = crypt.Sign(content, certificate.RawData); // здесь лежит бинарное представление подписи к документу Console.WriteLine("Создана подпись к документу."); // Теперь передадим в структуру информацию о файле. // Для этого воспользуемся универсальным полем DocumentAttachment — через него можно отправить любой тип. var documentAttachment = new DocumentAttachment { /* * Чтобы Диадок знал, какой тип документа вы хотите отправить, * нужно заполнить поле TypeNamedId (а также Function и Version, если у типа больше одной функции и версии). * Узнать список доступных типов можно через метод-справочник GetDocumentTypes. */ TypeNamedId = "nonformalized", // Теперь передадим сам файл неформализованного документа и сформированную к нему подпись: SignedContent = new SignedContent { Content = content, Signature = signature }, Comment = "Здесь можно указать любой текстовый комментарий, который нужно оставить к документу", CustomDocumentId = "Тут можно указать любой строковый идентификатор, например, для соответствия с вашей учётной системой", /* * У каждого типа документа в Диадоке может быть свой набор метаданных. * Их нужно указывать при отправке, если они обязательны. * Узнать набор требуемых метаданных для конкретного набора (тип-функция-версия-порядковый номер титула) * можно через тот же метод-справочник GetDocumentTypes: смотрите поля MetadataItems. * * Для нашего случая, связки nonformalized-default-v1, часть ответа метода GetDocumentTypes выглядит так: * * "MetadataItems": [ * { * "Id": "FileName", * "Type": "String", * "IsRequired": true, * "Source": "User" * }, * { * "Id": "DocumentNumber", * "Type": "String", * "IsRequired": false, * "Source": "User" * }, * { * "Id": "DocumentDate", * "Type": "Date", * "IsRequired": false, * "Source": "User" * } * ] * * Это нужно читать так: для отправки неформализованного документа * обязательно нужно указывать только те метаданные, у которых IsRequired=true, * а источник: User. Под условие подходит только FileName — имя файла документа. * * Другие метаданные (DocumentNumber — номер документа, DocumentDate — дата документа) необязательны к заполнению, * но их можно указать, и тогда Диадок будет возвращать их при запросе документа, * будет отображать в веб-интерфейсе и т.п. */ Metadata = { new MetadataItem { Key = "FileName", // Из эстетических соображений можно обрезать расширение файла, но это необязательно. // Указанное здесь значение будет влиять на то, как неформализованный документ будет называться в Диадоке. // Оно может отличаться от реального названия файла. Value = Path.GetFileNameWithoutExtension(NonformalizedDocumentPath) } } }; // Добавим информацию о документе в MessageToPost: messageToPost.DocumentAttachments.Add(documentAttachment); // Наконец отправляем подготовленный комплект документов через Диадок Console.WriteLine("Отправляем пакет из одного неформализованного документа..."); Console.WriteLine("Из ящика: " + messageToPost.FromBoxId); Console.WriteLine("В ящик: " + messageToPost.ToBoxId); var response = diadocApi.PostMessage(authToken, messageToPost); // При необходимости можно обработать ответ сервера (например, можно получить // и сохранить для последующей обработки идентификатор сообщения) Console.WriteLine("Документ был успешно загружен."); Console.WriteLine("MessageID: " + response.MessageId); Console.WriteLine("Количество сущностей в сообщении: " + response.Entities.Count); // В ответе будет две сущности, т.к. контент и подпись к нему хранятся отдельно друг от друга. // Выведем информацию о самом документе. Это можно сделать так: var responseDocument = response.Entities.FirstOrDefault(e => string.IsNullOrEmpty(e.ParentEntityId)); // т.к. у документа нет "родительских сущностей" Console.WriteLine("Идентификатор документа: " + responseDocument.EntityId); Console.WriteLine("Название документа: " + responseDocument.DocumentInfo.Title); }
public void Execute(ISession session) { api = new DiadocApi(/*ConfigurationManager.AppSettings["DiadokApi"]*/ "Analit-988b9e85-1b8e-40a9-b6bd-543790d0a7ec", "https://diadoc-api.kontur.ru", new WinApiCrypt()); token = api.Authenticate(ddkConfig.sender_login, ddkConfig.sender_passwd); box = api.GetMyOrganizations(token).Organizations[0].Boxes[0]; signers = new List <Signer>(); var msgs = GetMessages(); for (int i = 0; i < msgs.Item1.Count(); i++) { api.Delete(token, box.BoxId, msgs.Item2[i].MessageId, msgs.Item1[i].EntityId); } var msg = new MessageToPost(); NonformalizedAttachment nfa = new NonformalizedAttachment(); nfa.SignedContent = new SignedContent(); nfa.SignedContent.Content = Encoding.GetEncoding(1251).GetBytes("ТЕСТОВЫЙ НЕФОРМАЛИЗИРОВННЫЙ ДОКУМЕНТ"); nfa.SignedContent.SignWithTestSignature = true; nfa.FileName = "НеформализированныйДокумент.txt"; nfa.NeedRecipientSignature = true; nfa.DocumentDate = DateTime.UtcNow.ToString("dd.MM.yyyy"); nfa.DocumentNumber = DateTime.UtcNow.Millisecond.ToString(); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); msg.NonformalizedDocuments.Add(nfa); XmlDocumentAttachment sii = new XmlDocumentAttachment(); byte[] content = Encoding.GetEncoding(1251).GetBytes(DiadokFixtureData.InvoiceXml); byte[] sign = null; InvoiceInfo ii = api.ParseInvoiceXml(content); signers.Add(ii.Signer); GeneratedFile iiFile = api.GenerateInvoiceXml(token, ii); sii.SignedContent = new SignedContent(); sii.SignedContent.SignWithTestSignature = true; sii.SignedContent.Content = iiFile.Content; sii.SignedContent.Signature = sign; msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); msg.Invoices.Add(sii); XmlDocumentAttachment att12 = new XmlDocumentAttachment(); content = Encoding.GetEncoding(1251).GetBytes(DiadokFixtureData.Torg12Xml); Torg12SellerTitleInfo tsti12 = api.ParseTorg12SellerTitleXml(content); signers.Add(tsti12.Signer); iiFile = api.GenerateTorg12XmlForSeller(token, tsti12, true); att12.SignedContent = new SignedContent(); att12.SignedContent.SignWithTestSignature = true; att12.SignedContent.Content = iiFile.Content; att12.SignedContent.Signature = sign; msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.AddXmlTorg12SellerTitle(att12); msg.FromBoxId = ddkConfig.sender_boxid; msg.ToBoxId = ddkConfig.reciever_boxid; // пакет из трех api.PostMessage(token, msg); Thread.Sleep(TimeSpan.FromSeconds(3)); msg.NonformalizedDocuments.Clear(); msg.Invoices.Clear(); msg.XmlTorg12SellerTitles.Clear(); // инвойс msg.Invoices.Add(sii); api.PostMessage(token, msg); Thread.Sleep(TimeSpan.FromSeconds(3)); msg.Invoices.Clear(); msg.XmlTorg12SellerTitles.Clear(); // накладная msg.AddXmlTorg12SellerTitle(att12); api.PostMessage(token, msg); }
public static void RunSample() { Console.WriteLine("Пример отправки документа через Полку."); Console.WriteLine("Актуально для тяжеловесных файлов (больше мегабайта)"); Console.WriteLine("===================================================="); // Для использования API Диадока требуются: // 1. Крипто-API, предоставляемое операционной системой. Для систем на ОС Windows используйте класс WinApiCrypt. // 2. Экземпляр класса DiadocApi, проксирующий работу с Диадоком. var crypt = new WinApiCrypt(); var diadocApi = new DiadocApi( Constants.DefaultClientId, Constants.DefaultApiUrl, crypt); // Авторизуемся в Диадоке. В этом примере используем авторизацию через логин-пароль: var authToken = diadocApi.Authenticate(Constants.DefaultLogin, Constants.DefaultPassword); // Также можно использовать авторизацию по сертификату, она описана в примере Authenticate.cs // Для отправки комплекта документов требуется подготовить структуру MessageToPost, // которая и будет содержать отправляемый комплект документов. // Для начала, укажем в структуре идентификаторы отправителя и получателя: var messageToPost = new MessageToPost { FromBoxId = Constants.DefaultFromBoxId, ToBoxId = Constants.DefaultToBoxId }; // Отправим контент на Полку — временное хранилище для файлов, представляемое через API Диадока: var content = File.ReadAllBytes(NonformalizedDocumentPath); // здесь лежит бинарное представление неформализованного документа Console.WriteLine("Загружаем документ на Полку..."); var uploadedFileShelfName = diadocApi.UploadFileToShelf(authToken, content); Console.WriteLine("Успешно. Путь до документа на Полке: " + uploadedFileShelfName); // Подпишем контент через WinApiCrypt нашим сертификатом и тоже отправим на Полку: var certificate = new X509Certificate2(File.ReadAllBytes(Constants.CertificatePath)); Console.WriteLine("Создаём подпись..."); var signature = crypt.Sign(content, certificate.RawData); // здесь лежит бинарное представление подписи к документу Console.WriteLine("Создана подпись к документу."); Console.WriteLine("Загружаем подпись на Полку..."); var uploadedSignatureShelfName = diadocApi.UploadFileToShelf(authToken, signature); Console.WriteLine("Успешно. Путь до подписи на Полке: " + uploadedSignatureShelfName); // Теперь передадим в структуру информацию о файле. // Подробности заполнения типа и метаданных можно посмотреть в примере PostNonformalizedDocument.cs var documentAttachment = new DocumentAttachment { TypeNamedId = "nonformalized", // Здесь мы передаём не само бинарное представление, а только путь до Полки: SignedContent = new SignedContent { NameOnShelf = uploadedFileShelfName, SignatureNameOnShelf = uploadedSignatureShelfName }, Metadata = { new MetadataItem { Key = "FileName", Value = Path.GetFileNameWithoutExtension(NonformalizedDocumentPath) } } }; // Добавим информацию о документе в MessageToPost: messageToPost.DocumentAttachments.Add(documentAttachment); // Наконец отправляем подготовленный комплект документов через Диадок Console.WriteLine("Отправляем пакет из одного неформализованного документа..."); Console.WriteLine("Из ящика: " + messageToPost.FromBoxId); Console.WriteLine("В ящик: " + messageToPost.ToBoxId); var response = diadocApi.PostMessage(authToken, messageToPost); // При необходимости можно обработать ответ сервера (например, можно получить // и сохранить для последующей обработки идентификатор сообщения) Console.WriteLine("Документ был успешно загружен."); Console.WriteLine("MessageID: " + response.MessageId); Console.WriteLine("Количество сущностей в сообщении: " + response.Entities.Count); // В ответе будет две сущности, т.к. контент и подпись к нему хранятся отдельно друг от друга. // Выведем информацию о самом документе. Это можно сделать так: var responseDocument = response.Entities.FirstOrDefault(e => string.IsNullOrEmpty(e.ParentEntityId)); // т.к. у документа нет "родительских сущностей" Console.WriteLine("Идентификатор документа: " + responseDocument.EntityId); Console.WriteLine("Название документа: " + responseDocument.DocumentInfo.Title); }
public static void RunSample() { Console.WriteLine("Пример добавления извещения о получении к документу"); Console.WriteLine("==================================================="); // Для использования API Диадока требуются: // 1. Крипто-API, предоставляемое операционной системой. Для систем на ОС Windows используйте класс WinApiCrypt. // 2. Экземпляр класса DiadocApi, проксирующий работу с Диадоком. var crypt = new WinApiCrypt(); var diadocApi = new DiadocApi( Constants.DefaultClientId, Constants.DefaultApiUrl, crypt); // Авторизуемся в Диадоке. В этом примере используем авторизацию через логин-пароль: var authToken = diadocApi.Authenticate(Constants.DefaultLogin, Constants.DefaultPassword); // Также можно использовать авторизацию по сертификату, она описана в примере Authenticate.cs // Поищем в ящике документы, для которых нужно создать и подписать извещение о получении (он же ИоП). // Это можно сделать несколькими способами. Один из вариантов — через фильтрацию методом GetDocuments var documentList = diadocApi.GetDocuments( authToken, new DocumentsFilter { // Если вы успешно выполняли пример из PostUniversalTransferDocument820.cs, // в качестве ящика можно подставить ящик получателя BoxId = BoxId, FilterCategory = "Any.InboundHaveToCreateReceipt" // этот фильтр читается так: входящий документ любого типа, для которого нужно создать ИоП (на любую сущность) }); // В зависимости от документооборота, ИоПы могут быть и на другие сущности: // например, при работе с счетом-фактурой требуется отправить ИоП на подтверждение оператора ЭДО. // Подробнее о всех сущностях можно прочитать в документации: // http://api-docs.diadoc.ru/ru/latest/http/GenerateReceiptXml.html // http://api-docs.diadoc.ru/ru/latest/howto/example_receive_invoice.html // Поэтому для примера из выборки возьмём первый подходящий документ, для которого нет ИоПа только к титулу отправителя: string messageId = null; string documentId = null; foreach (var document in documentList.Documents) { var message = diadocApi.GetMessage(authToken, BoxId, document.MessageId); if (!HasReceiptForAttachment(message, document.EntityId)) { messageId = document.MessageId; documentId = document.EntityId; break; } } if (messageId == null && documentId == null) { Console.WriteLine("Подходящих документов нет, завершаем работу примера."); return; } Console.WriteLine($"Берём документ с идентификаторами MessageId={messageId}, EntityId={documentId}"); // Теперь приступим к созданию самого извещения о получении. // Это — технологический документ в формате XML. // Самый простой способ получить его: использовать соответствующий метод генерации Console.WriteLine("Создаём извещение о получении..."); var generatedReceipt = diadocApi.GenerateReceiptXml( authToken, BoxId, messageId, documentId, // здесь указываем идентификатор титула, т.к. мы создаём ИоП именно к нему new Signer { SignerDetails = new SignerDetails { FirstName = "Иван", Patronymic = "Иванович", Surname = "Иванов", Inn = "7750370238", JobTitle = "директор" } }); Console.WriteLine("Извещение о получении сгенерировано."); // ИоП, как и любой документ, также должен быть подписан. Создаём к нему подпись Console.WriteLine("Создаём подпись..."); var content = generatedReceipt.Content; var certificate = new X509Certificate2(File.ReadAllBytes(Constants.CertificatePath)); var signature = crypt.Sign(content, certificate.RawData); Console.WriteLine("Создана подпись к извещению о получении."); // Теперь мы готовы к отправке ИоПа. Делается это через метод PostMessagePatch var messagePatchToPost = new MessagePatchToPost { BoxId = BoxId, MessageId = messageId }; var receiptAttachment = new ReceiptAttachment { ParentEntityId = documentId, // наш ИоП будет относиться к документу, поэтому явно показываем, к какой сущности мы создаем ИоП SignedContent = new SignedContent { Content = content, Signature = signature } }; messagePatchToPost.Receipts.Add(receiptAttachment); var response = diadocApi.PostMessagePatch(authToken, messagePatchToPost); Console.WriteLine("Извещение о получении было успешно загружено."); var receipt = response.Entities.First( e => e.ParentEntityId == documentId && (e.AttachmentType == AttachmentType.Receipt || e.AttachmentType == AttachmentType.InvoiceReceipt)); Console.WriteLine($"Идентификатор: {receipt.EntityId}"); }