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) ?? "Не удалось выполнить операцию, попробуйте повторить позднее."); }); }
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}"); }