Ejemplo n.º 1
0
        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)
                              ?? "Не удалось выполнить операцию, попробуйте повторить позднее.");
            });
        }
Ejemplo n.º 2
0
        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, и потребуется вновь получить токен через методы выше.
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 8
0
        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}");
        }