/// <summary> /// Добавить в сообщение документ перед отправкой /// </summary> /// <param name="message">сообщение</param> /// <param name="document"></param> /// <param name="sign"></param> /// <returns></returns> public static Message AddDocumentToNewMessage(Message message, Document document, byte[] sign) { if (message == null) throw new ArgumentNullException("message"); if (document == null) throw new ArgumentNullException("document"); if (sign == null) throw new ArgumentNullException("sign"); if (string.IsNullOrEmpty(document.Id)) { throw new ArgumentException("Не указан идентификатор документа"); } if (message.Documents == null) message.Documents = new Document[0]; if (message.Signs == null) message.Signs = new Sign[0]; if (message.Documents.Any(d => d.Id == document.Id)) throw new ArgumentException("Документ с идентификатором \"{0}\" уже добавлен в сообщение", document.Id); var documents = new List<Document>(message.Documents); documents.Add(document); message.Documents = documents.ToArray(); var signs = new List<Sign>(message.Signs); signs.Add(new Sign() { Id = Guid.NewGuid().ToString(), DocumentId = document.Id, Raw = sign }); message.Signs = signs.ToArray(); return message; }
/// <summary> /// Создать сообщение с СД УОУ (регламент ЭСФ) /// </summary> /// <param name="message"></param> /// <param name="document"></param> /// <param name="certificate"></param> /// <returns></returns> public Message GenerateInvoiceAmendmentRequest(Message message, Document document, string text, X509Certificate2 certificate) { if (message == null) throw new ArgumentNullException("message"); if (document == null) throw new ArgumentNullException("document"); if (certificate == null) throw new ArgumentNullException("certificate"); var amendmentRequest = client.GenerateInvoiceAmendmentRequest(CurrentBox, document.Id, text); return CreateServiceDocumentMessage(message, document, certificate, DocumentType.ServiceInvoiceAmendmentRequest, amendmentRequest); }
/// <summary> /// Создать сообщение с подписью (общий регламент) /// </summary> /// <param name="message"></param> /// <param name="document"></param> /// <param name="certificate"></param> /// <returns></returns> public Message CreateSign(Message message, Document document, X509Certificate2 certificate) { if (message == null) throw new ArgumentNullException("message"); if (document == null) throw new ArgumentNullException("document"); if (certificate == null) throw new ArgumentNullException("certificate"); if (document.Content == null) throw new ArgumentException("Содержимое документа не загружено"); var sign = CryptoApiHelper.Sign(certificate, document.Content, true); var signMessage = new Message() { Id = Guid.NewGuid().ToString(), From = CurrentBox, Recipients = message.GetRecipientListForSender(CurrentBox), Signs = new [] { new Sign() { DocumentId = document.Id, Raw = sign, Id = Guid.NewGuid().ToString() } } }; return signMessage; }
public Message CreateServiceDocumentMessage(Message message, Document document, X509Certificate2 certificate2, DocumentType documentType, NamedContent generatedNotice) { var noticeMessage = AddDocumentToNewMessage( new Message() { Id = Guid.NewGuid().ToString(), From = CurrentBox, Recipients = message.GetRecipientListForSender(CurrentBox), }, new Document() { Id = (Guid.NewGuid().ToString()), DocumentType = documentType, ParentDocumentId = document.Id, FileName = generatedNotice.Name, Content = generatedNotice.Content }, CryptoApiHelper.Sign(certificate2, generatedNotice.Content, true)); return noticeMessage; }
/// <summary> /// Создать сообщение с СД ИОП (общий регламент) /// </summary> /// <param name="message"></param> /// <param name="document"></param> /// <param name="certificate2"></param> /// <returns></returns> public Message CreateReceipt(Message message, Document document, X509Certificate2 certificate2) { if (message == null) throw new ArgumentNullException("message"); if (document == null) throw new ArgumentNullException("document"); if (certificate2 == null) throw new ArgumentNullException("certificate2"); var deliveryConfirmation = client.GenerateDeliveryConfirmation(CurrentBox, document.Id); return CreateServiceDocumentMessage(message, document, certificate2, DocumentType.ServiceReceipt, deliveryConfirmation); }
/// <summary> /// Пример авторизации по сертификату /// получение данных по ИНН об организации-получателе /// отправка документа с подписью сертификатом пользователя /// отправка документ без подписания /// </summary> /// <param name="args"></param> private static void Main(string[] args) { var url = "https://service.synerdocs.ru/exchangeservice.svc"; var appId = new Guid().ToString(); var client = new Client(url, false, false, "", "WSHttpsBinding_IExchangeService"); // сертификат для входа по сертификату и подписания var certificate = TryInstallOrGetCertificate(); if (certificate == null) return; Console.WriteLine("Успешно получен сертификат с отпечатком: " + certificate.Thumbprint); // авторизуемся по сертификату if (client.AuthenticateWithCertificate(certificate.Thumbprint, appId)) { Console.WriteLine("Успешная авторизация по сертификату, получен токен:"); Console.WriteLine(client.Token); } else { Console.WriteLine("Ошибка авторизации по сертификату"); } // ИНН организации-получателя var inn = "1839839904"; // не знаем КПП, при пустом значении - должно найти головное подразделение организации var kpp = ""; // поиск организации получателя по атрибутам var organizations = client.GetOrganizationListByInnKpp(inn, kpp); foreach (var organization in organizations) Console.WriteLine(organization.Name); // получаем содержимое неформализованного документа из файла на локальном компьютере var filesDir = "../../../../.."; // пример подписи файлов с локального компьютера var filePath = filesDir + "/Documents/Untyped 3.txt"; var filePath2 = filesDir + "/Documents/Untyped 1.png"; var fileBytes = File.ReadAllBytes(filePath); var fileBytes2 = File.ReadAllBytes(filePath2); // создание подписей к бинарному содержимому файлов, подписание с помощью выбранного ранее сертификата var signature = CryptoApiHelper.Sign(certificate, fileBytes, true); var signature2 = CryptoApiHelper.Sign(certificate, fileBytes2, true); // получение текущего ящика var boxInfo = client.GetBoxes().FirstOrDefault(); if (boxInfo == null) { Console.WriteLine("Ошибка при получении ящиков"); return; } var currentBox = boxInfo.Address; // создание документа var document = new Document { Id = Guid.NewGuid().ToString(), DocumentType = DocumentType.Untyped, UntypedKind = null, FileName = Path.GetFileName(filePath), Content = fileBytes, Card = null, NeedSign = false }; // создание еще одного документа (опционально) var document2 = new Document { Id = Guid.NewGuid().ToString(), DocumentType = DocumentType.Untyped, UntypedKind = null, FileName = Path.GetFileName(filePath2), Content = fileBytes2, Card = null, NeedSign = false }; // создаем сообщение для отправки var message = new Message { // генерируем уникальный идентификатор для сообщения Id = Guid.NewGuid().ToString(), // указываем свой текущий ящик (ящик отправителя) From = currentBox, // документы Documents = new[] { document, document2 }, // получатели Recipients = organizations.Select(x => new MessageRecipient { OrganizationBoxId = x.BoxAddress }).ToArray(), // прикрепляем подписи Signs = new[] { new Sign { Id = Guid.NewGuid().ToString(), DocumentId = document.Id, Raw = signature }, new Sign { Id = Guid.NewGuid().ToString(), DocumentId = document2.Id, Raw = signature2 } } }; SentMessage result; try { result = client.SendMessage(message); } catch (Exception ex) { Console.WriteLine("Ошибка при отправке документов: " + ex.Message); Console.ReadKey(); return; } Console.WriteLine("Успешно отправлено исходящее сообщение MessageId = {0}", result.MessageId); Console.WriteLine("Для выхода нажмите enter"); Console.ReadLine(); }
public Message() { Documents = new Document[0]; Signs = new Sign[0]; }
/// <summary> /// Создать сообщение с СД ИОП (регламент ЭСФ) /// </summary> /// <returns></returns> public Message CreateInvoiceReceipt(Message message, Document document, X509Certificate2 certificate2) { if (message == null) throw new ArgumentNullException("message"); if (document == null) throw new ArgumentNullException("document"); if (certificate2 == null) throw new ArgumentNullException("certificate2"); var generatedNotice = client.GenerateInvoiceReceipt(CurrentBox, document.Id); return CreateServiceDocumentMessage(message, document, certificate2, DocumentType.ServiceInvoiceReceipt, generatedNotice); }
private void ProcessTitleBuyer(Document document) { var documentInfo = _context.ServiceClient.GetFullDocumentInfo(_context.CurrentBox, document.ParentDocumentId); Console.Out.WriteLine("Документ {0} подписан", DocumentShortName(documentInfo)); }
private void ProcessRejectSign(Document document) { var documentInfo = _context.ServiceClient.GetFullDocumentInfo(_context.CurrentBox, document.ParentDocumentId); Console.Out.WriteLine("Отказано в подписи под документом {0}", DocumentShortName(documentInfo)); }
/// <summary> /// Обработка входящего документа /// </summary> /// <param name="message"></param> /// <param name="document"></param> private void ProcessIncomingDocument(Message message, Document document) { // в зависимости от типа документа показывать атрибуты // для СФ это карточка, статус, подпись, имя файла // для СД это тип (по типу разное отображение), подпись, к какому документу относится // для НД название, подпись, ожидается ли подпись var documentInfo = _context.ServiceClient.GetFullDocumentInfo(_context.CurrentBox, document.Id); var documentType = (DocumentType)documentInfo.Document.DocumentTypeEnum.Code; UserInput.Separator(); Console.Out.Write("Обрабатывается "); PrintDocumentInfo(documentInfo); // НД if (documentType == DocumentType.Untyped) ProcessUntypedDocument(message, documentInfo); // НД: ИОП else if (documentType == DocumentType.ServiceReceipt) ProcessDeliveryConfirmation(document); // НД: УОУ else if (documentType == DocumentType.ServiceAmendmentRequest) ProcessRejectSign(document); // СФ else if (documentType == DocumentType.Invoice) ProcessInvoice(message, documentInfo); // СФ: подтверждение о дате отправки/приема else if (documentType == DocumentType.ServiceInvoiceConfirmation) ProcessServiceInvoiceConfirmation(message, documentInfo); // СФ: УОУ else if (documentType == DocumentType.ServiceInvoiceAmendmentRequest) ProcessServiceInvoiceAmendmentRequest(message, documentInfo); // Товарная накладная / Акт о выполнении работ: титул продавца / титул исполнителя else if (documentType.In(DocumentType.WaybillSeller, DocumentType.ActOfWorkSeller)) ProcessFormalizedDocument(message, documentInfo); // Товарная накладная / Акт о выполнении работ : титул покупателя / заказчика else if (documentType.In(DocumentType.WaybillBuyer, DocumentType.ActOfWorkBuyer)) ProcessTitleBuyer(document); // Предложение об аннулировании else if (documentType == DocumentType.RevocationOffer) ProcessRevocationOffer(message, documentInfo); // TODO сделать методы автоматической генерации служебных документов в SDK }
private void ProcessDeliveryConfirmation(Document document) { var documentInfo = _context.ServiceClient.GetFullDocumentInfo(_context.CurrentBox, document.ParentDocumentId); Console.Out.WriteLine("Документ {0} дошел до получателя", DocumentShortName(documentInfo)); }
/// <summary> /// Отправка заявления об участии в ЭДО СФ /// </summary> public void SendStatementOfInvoiceReglament() { var certificate = _context.Certificate; var boxId = _context.CurrentBox; // требуется авторизация по сертификату if (certificate == null) ChooseCertificate(); try { // создадим заявление var statement = _context.ServiceClient.GenerateStatementOfInvoiceReglament(boxId); // подпишем заявление var sign = Sign(statement.Content); if (sign == null) { UserInput.Error("Не удалось подписать заявление об участии в ЭДО СФ"); return; } var document = new Document { Id = Guid.NewGuid().ToString(), DocumentType = DocumentType.Untyped, UntypedKind = UntypedKind.StatementOfInvoiceReglament, FileName = statement.Name, Content = statement.Content }; // отправим сообщение с заявлением var message = new MessageOfStatement { Id = Guid.NewGuid().ToString(), FromBoxId = _context.CurrentBox, Statement = document, Sign = new Sign { Id = Guid.NewGuid().ToString(), DocumentId = document.Id, Raw = sign } }; _context.ServiceClient.SendStatementOfInvoiceReglament(message); UserInput.Success("Заявление об участии в ЭДО СФ успешно отправлено!"); } catch (ServerException ex) { UserInput.Error(ex.Message); return; } }
private byte[] GetDocumentContent(Document document) { return document.Content ?? (document.Content = _context.ServiceClient.GetDocumentContent(_context.CurrentBox, document.Id)); }
private void EnsureDocumentContentLoaded(Document document) { if (document.Content == null) GetDocumentContent(document); }
/// <summary> /// Преобразование документа в документ черновика /// </summary> /// <param name="document"></param> /// <returns></returns> private static DraftDocument ConvertToDraftDocument(Document document) { return new DraftDocument { Id = document.Id, DocumentType = document.DocumentType, Name = document.Name ?? document.FileName, FileName = document.FileName, FileSize = document.FileSize, Content = document.Content, Card = document.Card, Comment = document.Comment, NeedSign = document.NeedSign, NeedReceipt = document.NeedReceipt, ParentDocumentId = document.ParentDocumentId }; }
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="document"></param> /// <param name="certificate"></param> /// <returns></returns> public Message CreateAmendmentRequest(Message message, Document document, string text, X509Certificate2 certificate) { var amendmentRequest = client.GenerateAmendmentRequest(CurrentBox, document.Id, text); return CreateServiceDocumentMessage(message, document, certificate, DocumentType.ServiceAmendmentRequest, amendmentRequest); }
/// <summary> /// Добавить документ к неотправленному сообщению /// </summary> /// <param name="message">Сообщение</param> /// <param name="document">Документ</param> /// <param name="sign">Подпись в формате CMS</param> private Message AddDocumentToNewMessage(Message message, Document document, byte[] sign) { return MessageFactory.AddDocumentToNewMessage(message, document, sign); }
/// <summary> /// Пример авторизации по сертификату /// получение данных по ИНН об организации-получателе /// отправка документа с подписью сертификатом пользователя /// отправка документов без подписания /// /// отправка идет так: /// /// сообщение1 - получателю1 без указания подразления /// документ1 /// документ2 /// </summary> /// <param name="args"></param> private static void Main(string[] args) { var url = "https://service.synerdocs.ru/exchangeservice.svc"; var client = new Client(url, false, false, "", "WSHttpsBinding_IExchangeService"); // авторизация по логину и паролю (тут возможно использовать также // авторизацию по сертификату при необходимости) var login = "******"; var password = "******"; if (client.Authenticate(login, password)) { Console.WriteLine("Успешная авторизация, получен токен:"); Console.WriteLine(client.Token); } else { Console.WriteLine("Ошибка авторизации"); Console.ReadKey(); return; } // получение текущего ящика var currentBoxInfo = client.GetBoxes().FirstOrDefault(); if (currentBoxInfo == null) { Console.WriteLine("Ошибка при получении ящиков"); return; } // выбор текущего ящика - от него будем отправлять документы // в простом случае - у пользователя доступен только один ящик // а если пользователь состоит в нескольких организациях - ящиков может быть несколько var currentBox = currentBoxInfo.Address; // ИНН организации-получателя var inn = "1839839970"; // пусть не знаем КПП, при пустом значении - должно автоматически быть получено головное // при получении списка организации var kpp = ""; // поиск организации получателя по атрибутам var organizations = client.GetOrganizationListByInnKpp(inn, kpp); // отладочный вывод некоторой информации о найденных организациях Console.WriteLine("Организации - получатели:"); foreach (var organization in organizations) Console.WriteLine(organization.Name); // создание списка получателей документов в сообщении var messageRecipients = organizations.Select(x => new MessageRecipient { // ящик получателя, при этом автоматически будет выбрано головное подразделение, // т.к. явно не указали подразделение OrganizationBoxId = x.BoxAddress }).ToList(); // добавление еще одного получателя: // выбор по определенному КПП подразделения организации - получателя var moreRecipientKpp = "243456789"; var moreRecipient = client.GetOrganizationByInnKpp("1839840035", null); // вывод некоторой инфомрации о найденном получателе: Console.WriteLine("Организация - дополнительный получатель:"); Console.WriteLine(moreRecipient.Name); // получим все подразделения организации и выберем нужное по КПП // в параметр метода передается текущий выбранный ящик var departments = client.GetOrganizationStructure(currentBox, moreRecipient.OrganizationId); var moreRecipientDepartment = departments.FirstOrDefault(x => x.Kpp == moreRecipientKpp); if (moreRecipientDepartment == null) { Console.WriteLine("Не удалось найти подразделение организации - дополительного получателя по КПП - " + moreRecipientKpp); return; } // ! т.к. Отправка документов без подписи нескольким контрагентам невозможна, // поэтому каждый из списков получателей содержим только одного получателя // Но например при отправке документов с подписью возможно отправлять документы сразу нескольких получателям // Пример указания определенного подразделения организации - получателя: // добавим полученную информацию о подразделении получателя в нужный список получателей var messageRecipientsWithDepartments = new List<MessageRecipient> { new MessageRecipient { // ящик организации - получателя OrganizationBoxId = moreRecipient.BoxAddress, // ИД подразделения организации - получателя (необязательный параметр) DepartmentId = moreRecipientDepartment.Id } }; // содержимое неформализованного документа из файла на локальном компьютере var filesDir = "../../../../.."; var filePath = filesDir + "/Documents/Untyped 3.txt"; var fileBytes = File.ReadAllBytes(filePath); // Пример создание документов: // созданный объект - документ можно использовать при отправке в сообщениях // только 1 раз, т.к. поля должны быть уникальными var document1 = new Document { Id = Guid.NewGuid().ToString(), DocumentType = DocumentType.Untyped, UntypedKind = null, FileName = "Отправка без подписи - первый документ1 - " + Path.GetFileName(filePath), Content = fileBytes, Card = null, NeedSign = false }; // создание 2го документа var document2 = new Document { Id = Guid.NewGuid().ToString(), DocumentType = DocumentType.Untyped, UntypedKind = null, FileName = "Отправка без подписи - второй документ2 - " + Path.GetFileName(filePath), Content = fileBytes, Card = null, NeedSign = false }; // создаем сообщение для отправки var unsignedMessage = new UnsignedMessage { From = currentBox, // документы в сообщение Documents = new[] { document1, document2 }, // получатели Recipients = messageRecipients.ToArray() }; // создаем сообщение для отправки по второму списку получателей - для примера c указанием подразделений // создание 3го документа var document3 = new Document { // для исключения дублирования ID документов - всегда необходимо создание уникальных идентификаторов документов Id = Guid.NewGuid().ToString(), DocumentType = DocumentType.Untyped, UntypedKind = null, FileName = "Отправка без подписи - первый документ3 - " + Path.GetFileName(filePath), Content = fileBytes, Card = null, NeedSign = false }; // создание 4го документа var document4 = new Document { Id = Guid.NewGuid().ToString(), DocumentType = DocumentType.Untyped, UntypedKind = null, FileName = "Отправка без подписи - второй документ4 - " + Path.GetFileName(filePath), Content = fileBytes, Card = null, NeedSign = false }; // создание 2го сообщения var unsignedMessage2 = new UnsignedMessage { From = currentBox, // документы в сообщение Documents = new[] { document3, document4 }, // получатели Recipients = messageRecipientsWithDepartments.ToArray() }; // пример отправки двух сообщений с разными наборами получателей // отправляем сообщение 1 SentMessage result1; try { result1 = client.SendUnsignedMessage(unsignedMessage); Console.WriteLine("Успешно отправлено исходящее сообщение с документами без подписи 1"); } catch (Exception ex) { Console.WriteLine("Ошибка при отправке сообщения 1" + ex.Message); Console.ReadKey(); return; } // отправляем сообщение 2 SentMessage result2; try { result2 = client.SendUnsignedMessage(unsignedMessage2); Console.WriteLine("Успешно отправлено исходящее сообщение с документами без подписи 2"); } catch (Exception ex) { Console.WriteLine("Ошибка при отправке сообщения 2" + ex.Message); Console.ReadKey(); return; } Console.WriteLine("Успешно отправлено исходящее сообщения"); Console.WriteLine("Для выхода нажмите enter"); Console.ReadLine(); }
private byte[] GetDocuemntContent(Document document) { if (document.Content == null) { // содержимое больших документов (> 1Mb) загружается отдельным запросом document.Content = context.ServiceClient.GetDocumentContent(context.CurrentBox, document.Id); } return document.Content; }