1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
| using Diadoc.Api;
using Diadoc.Api.Cryptography;
using Diadoc.Api.Proto.Events;
using Diadoc.Api.Proto.Invoicing;
using NLog;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
namespace diadoc_cnsl
{
class Program
{
private static Logger logger = LogManager.GetCurrentClassLogger(); //log
// URL веб-сервиса Диадок
private const string DefaultApiUrl = "https://diadoc-api.kontur.ru";
// идентификатор клиента
private const string DefaultClientId = "11111111111111";
// Для использования Диадок требуются:
// 1. Крипто-API, предоставляемое операционной системой (доступно через класс WinApiCrypt)
// 2. Экземпляр класса DiadocApi, проксирующий работу с веб-сервисом Диадок
private static WinApiCrypt Crypt = new WinApiCrypt();
public static readonly DiadocApi Api = new DiadocApi(
DefaultClientId,
DefaultApiUrl,
Crypt);
// Логин для авторизации на сервере Диадок
private const string DefaultLogin = "11111111111111";
// Пароль для авторизации на сервере Диадок
private const string DefaultPassword = "111111111111";
// Имя файла, содержимое которого будет отправлено через Диадок
const string FileToSendName = "C:\\out_list.csv";
private static byte[] ReadFileContent(string fName)
{
using (var file = new FileStream(fName, FileMode.Open))
{
var buffer = new MemoryStream();
var data = new byte[4000];
int count;
while ((count = file.Read(data, 0, data.Length)) > 0)
{
buffer.Write(data, 0, count);
}
return buffer.ToArray();
}
}
// Файл с данными сертификата, который следует использовать для подписи
private const string FileWithCertName = "D:\\c#_proj\\diadoc\\cert\\cer.cer";
public static void PostLargeNonformalized(string DefaultFromBoxId, string DefaultToBoxId)
{
// Для использования Диадок требуются:
// 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);
}
private static GeneratedFile GenerateinvoiceXml(string authToken)
{
var certContent = ReadFileContent(FileWithCertName);
var signer = new Signer
{
SignerCertificate = certContent
};
var content = new InvoiceInfo()
{
// заполняем согласно структуре InvoiceInfo
InvoiceDate = DateTime.Now.ToString(), // дата СФ
InvoiceNumber = "aaa", // номер СФ
Signer = signer,
Total = "1000"
};
return Api.GenerateInvoiceXml(authToken, content);
}
// отправка счета-фактуры
private static void SendInvoiceXml(string authToken, string box, string tobox)
{
var fileToSend = GenerateinvoiceXml(authToken);
var messageAttachment = new XmlDocumentAttachment
{
SignedContent = new SignedContent //файл подписи
{
Content = fileToSend.Content,
Signature = new byte[0] //подпись отправителя
}
};
var messageToPost = new MessageToPost
{
FromBoxId = box,
ToBoxId = tobox,
Invoices = { messageAttachment }
};
Api.PostMessage(authToken, messageToPost); //см. "Как авторизоваться в системе"
}
//получение подтверждения оператора, формирование и отправка извещения о получении подтверждения
/*
private void GetInvoiceConfirmationAndSendInvoiceReceipt(string authToken)
{
var invoiceDocument = "fkfkjfjkj";
var boxId = "идентификатор ящика отправителя";
var signer = new Signer
{
SignerCertificate = new byte[0] ,
SignerCertificateThumbprint = "отпечаток сертификата",
SignerDetails =
{
FirstName = "Имя",
Surname = "Фамилия",
Patronymic = "Отчество",
Inn = "ИНН",
JobTitle = "Должность",
SoleProprietorRegistrationCertificate = "Св-во о регистрации ИП"
}
};
//получение подтверждения оператора
var invoiceConfirmation = Api.GetMessage(authToken, boxId, invoiceDocument.MessageId, invoiceDocument.EntityId);
//формирование извещения о получении подтверждения
var invoiceReceipt = Api.GenerateInvoiceDocumentReceiptXml(authToken, invoiceDocument.MessageId, invoiceConfirmation.AttachmentId, signer);
//отправка извещения
var messagePatchToPost = new MessagePatchToPost
{
BoxId = boxId,
MessageId = invoiceDocument.MessageId,
ReceiptAttachment =
{
new ReceiptAttachment
{
ParentEntityId = invoiceDocument.EntityId,
SignedContent = new SignedContent //файл подписи
{
Content = invoiceDocument.Content,
Signature = new byte[0] //подпись продавца
}
}
}
};
Api.PostMessagePatch(authToken, messagePatchToPost);
}*/
static void Main(string[] args)
{
try //попытка подключения
{
// Можно использовать либо аутентификацию по логину/паролю, либо по сертификату
var authTokenLogin = Api.Authenticate(DefaultLogin, DefaultPassword); // по паре логин/пароль
//получаем свою организацию
var all = Api.GetOrganizationsByInnKpp("111111111", "1111111111");
// Console.WriteLine(all);
// Console.WriteLine(all.Organizations[0].OrgId);
string box = all.Organizations[0].Boxes[0].BoxId;
//uuid организации
string myOrgId = all.Organizations[0].OrgId;
//все контрагенты
var cntrs = Api.GetCounteragents(authTokenLogin, myOrgId, null, null);
string cntr_id = cntrs.Counteragents[0].IndexKey; //уникальный ключ для метода GetCounteragents(1,2,3,cntr_id)
string orgId = cntrs.Counteragents[0].Organization.OrgId; //ид чужой организации
var cntr = Api.GetCounteragent(authTokenLogin, myOrgId, orgId); //весь контрагент
string tobox = cntr.Organization.Boxes[0].BoxId;
SendInvoiceXml(authTokenLogin, box, tobox);
//PostLargeNonformalized(box, tobox);
Console.WriteLine(tobox);
Console.Read();
}
catch (Exception e)
{
logger.Debug("Except{0}", e, null);
Console.Read();
}
}
}
} |