Version 1.3 by Roelof Zwaan on 2021/11/23 11:40

Show last authors
1 {{toc/}}
2
3
4 = Firewall IP-Adresssen van TerraIndex =
5
6 Onze IP-adressen:
7
8 ingaand [[Web.terraindex.com>>url:http://Web.terraindex.com]]
9 137.116.199.164
10
11 ingaand [[Test.terraindex.com>>url:http://Test.terraindex.com]]
12 104.45.9.128
13
14 Productie uitgaand
15 40.115.34.64
16
17 Test uitgaand
18 13.73.138.173
19
20 CD/CI uitgaand
21 40.114.238.16
22
23 --Kantoor VPN uitgaand  (niet meer in gebruik, was de oude OpenVPN)
24 10.33.66.215--
25
26 Kantoor uitgaand
27 213.124.115.132
28
29 --Oude Citrix uitgaand (citrix is ook verhuisd, dit is niet meer in gebruik)
30 83.96.194.140--
31
32
33 = Labaanlever bestanden uitwisseling =
34
35 == Oplossing/Design ==
36
37
38 (% class="table-hover" %)
39 |**Action**|**TerraIndex**| |**Laboratorium**|**Parameters/Message**|**Remarks**|**ResultCodes**
40 |1|Sends a request to the function: GetCustomers().|=>| |**WebserviceUsername (string), **
41 **WebservicePassword (string),**
42 **CustomerUsername (string)**| |
43 |2| | |Receives the request and check the customers this username and searches the dateLastChanged for this Customer.| | |
44 |3| |<=|Sends back the list of customers with the lastChangedTimestamp|ResultCode (),
45 ErrorMessage (string),
46 List<customer> , Customer:
47 CustomerCode (string),
48 CustomerName (string),
49 LabID (int),
50 LabName (string),
51 ChangedTimeStamp (DateTime)|We receive the dateTimestamp instead of sending it, so we always get the full list and we are also able to delete customercodes.|1 = Success,
52 2 = GeneralError,
53 3 = WrongSIKBVersion,
54 4 = InvalidCredentials,
55 5 = CustomerUsernameInvalid,
56 6 = CustomerUsernameNotValidForCustomerCode
57 7 = FileContentProblem,
58 8 = InvalidOrderId,
59 9 = OrderIdAlreadyApproved
60 10 = PDFNotAvailable
61 |4|Receives the list of Customers, and will check for each customer it needs to request a new/changed labdelivery file based on the ChangedTimestamp.| | | |If a customer is not longer in this list, TerraIndex can remove this customercode from the customer database.|
62 |5|Sends a request to the function: GetProductList() if it has changed.|=>| |**WebserviceUsername (string), **
63 **WebservicePassword (string),**
64 **CustomerUsername (string),**
65 LabID (int),
66 CustomerCode (string),
67 LanguageCode (string, default 'nld' volgens ISO 639-3-codes),
68 SIKBVersion (string, default: '13.4.0'),
69 UseZipStream/UseZip (bool, default: 'false')|(((
70 We start with dutch, then extend with multiple languages, TerraIndex is in the lead to request multiple languages.
71 TerraIndex uses: 'fra', 'nld', 'eng', 'spa', 'deu', 'ita', 'por', 'dan'
72
73
74 Besides SIKB 13.4.0, TerraIndex also supports 9.0.0/8.0.0 etc.
75 )))|
76 |6| | |Reveives a request to create a labdelivery file in a certain version of SIKB. It will generate the file.| | |
77 |7| |<=|Sends back the SIKB file, as a Base64 encoded string, with or without using a zipstream.|ResultCode (),
78 ErrorMessage (string),
79 FileContent_Base64 (string),
80 UseZipStream/UseZip (bool, default: 'false')| |1 = Success,
81 2 = GeneralError,
82 3 = WrongSIKBVersion,
83 4 = InvalidCredentials,
84 5 = CustomerUsernameInvalid,
85 6 = CustomerUsernameNotValidForCustomerCode
86 7 = FileContentProblem,
87 8 = InvalidOrderId,
88 9 = OrderIdAlreadyApproved
89 10 = PDFNotAvailable
90 |8|Receives the DeliveryFile and saves the file for import into customer database.| | | | |
91 |9|Go back to step 5, for every Customer code, every language.| | | | |
92 |10|Process the LabDeliveryFiles| | | | |
93
94
95 == Get Customers (POST) ==
96
97 === Request example ===
98
99 |(((
100 public GetCustomersCall.Response GetCustomers(string WebserviceUsername, string WebservicePassword, string CustomerUsername)
101
102 {
103
104 GetCustomersCall.Response set = new GetCustomersCall.Response();
105
106
107 try
108
109 {
110
111
112 var content = new FormUrlEncodedContent(new[]
113
114 {
115
116 new KeyValuePair<string, string>("userName", WebserviceUsername),
117
118 new KeyValuePair<string, string>("password", WebservicePassword),
119
120 new KeyValuePair<string, string>("customerUsername", CustomerUsername),
121
122 });
123
124
125 HttpResponseMessage response = _HttpClient.PostAsync(_HttpClient.BaseAddress + "/GetCustomers", content).Result;
126
127 response.EnsureSuccessStatusCode();
128
129 string responseMessage = response.Content.ReadAsStringAsync().Result;
130
131
132 if (string.IsNullOrEmpty(responseMessage))
133
134 {
135
136 throw new Exception("Empty response from: [" + _HttpClient.BaseAddress + " / GetCustomers" + "]");
137
138 }
139
140 using (var ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseMessage~)~)~)
141
142 {
143
144 XmlSerializer serializer = new XmlSerializer(typeof(GetCustomersCall.Response));
145
146 set = (GetCustomersCall.Response)serializer.Deserialize(ms);                  
147
148 }
149
150
151 }
152
153 catch (Exception ex)
154
155 {
156
157 #region handle exception
158
159
160 set.Status = new BusinessEntities.LabRestService.GetCustomersCall.ResponseStatus();
161
162 set.Status.StatusCode = ((int)ResultCodes.GeneralError).ToString();              
163
164 set.Status.ErrorMessage = "Exception occurred in GetCustomers (username: " + WebserviceUsername + ", password: " + WebservicePassword + ") with message: " + ex.Message;
165
166
167 ex.Data.Add("WebserviceUsername", WebserviceUsername);
168
169 ex.Data.Add("WebservicePassword", WebservicePassword);
170
171 ex.Data.Add("CustomerUsername", CustomerUsername);
172
173
174 ExceptionHandler.HandleException(ex);
175
176 #endregion
177
178 }
179
180
181 return set;
182
183 }
184 )))
185
186 |(((
187 POST https:~/~/<URL>/GetCustomers HTTP/1.1
188
189 Content-Type: application/x-www-form-urlencoded
190
191 Host: 81.175.89.24
192
193 Content-Length: 115
194
195 Expect: 100-continue
196
197
198 userName=<webservice_username>&password=<Webservice_password>&customerUsername=<customer_username or token>
199 )))
200
201 === Response example ===
202
203 |(((
204 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
205
206 <Response><Customers>
207
208 <Customer LabId="1" LabName="Example Laboratorium" CustomerId="300" CustomerName="Adviesbureau De bodemkoning - Rotterdam" LastModifiedOnClient="2019-05-08T11:05:14.17+02:00" />
209
210 <Customer LabId="1" LabName="Example Laboratorium" CustomerId="656" CustomerName="Adviesbureau De bodemkoning - Delft" LastModifiedOnClient="2019-04-19T13:20:10.123+02:00" />
211
212 </Customers>
213
214 <Status>
215
216 <StatusCode>1</StatusCode>
217
218 <StatusCodeDescription>OK</StatusCodeDescription>
219
220 <ErrorMessage></ErrorMessage>
221
222 </Status>
223
224 </Response>
225 )))
226
227
228 == Get Products (POST) ==
229
230 === Request example ===
231
232 |(((
233 public GetProductsCall.Response GetProductList(string WebserviceUsername, string WebservicePassword, string CustomerUsername, string customerid, int labid, string sikbVersion, string languageCode)
234
235 {
236
237
238 GetProductsCall.Response set = new GetProductsCall.Response();
239
240
241 try
242
243 {
244
245 bool useZipstream = true;
246
247 var content = new FormUrlEncodedContent(new[]
248
249 {
250
251 new KeyValuePair<string, string>("userName", WebserviceUsername),
252
253 new KeyValuePair<string, string>("password", WebservicePassword),
254
255 new KeyValuePair<string, string>("customerUsername", CustomerUsername),
256
257 new KeyValuePair<string, string>("languageCode", languageCode),
258
259 new KeyValuePair<string, string>("clientId", customerid),
260
261 new KeyValuePair<string, string>("sikbVersion", sikbVersion),
262
263 new KeyValuePair<string, string>("useZip", useZipstream.ToString() ),
264
265 });
266
267
268 HttpResponseMessage response = _HttpClient.PostAsync(_HttpClient.BaseAddress + "/GetProducts", content).Result;
269
270 response.EnsureSuccessStatusCode();
271
272 string responseMessage = response.Content.ReadAsStringAsync().Result;
273
274
275 if (string.IsNullOrEmpty(responseMessage))
276
277 {
278
279 throw new Exception("Empty response from: [" + _HttpClient.BaseAddress + " /GetProducts" + "]");
280
281 }
282
283 using (var ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseMessage~)~)~)
284
285 {
286
287 XmlSerializer serializer = new XmlSerializer(typeof(GetProductsCall.Response));
288
289 set = (GetProductsCall.Response)serializer.Deserialize(ms);
290
291 }
292
293
294 if (useZipstream && !string.IsNullOrEmpty(set.FileContent))
295
296 {
297
298 ~/~/convert from base64 string back to normal
299
300 ~/~/first check for real Base64, by checking there is no 'xml'  in it
301
302 if (!set.FileContent.Contains("<labaanlevering"))
303
304 {
305
306 set.FileContent = ZipStreamHelper.DecompressBase64StringToString(set.FileContent);
307
308 }
309
310 }
311
312
313 }
314
315 catch (Exception ex)
316
317 {
318
319 #region handle exception
320
321
322 set.Status = new BusinessEntities.LabRestService.GetProductsCall.ResponseStatus();
323
324 set.Status.StatusCode = ((int)ResultCodes.GeneralError).ToString();
325
326 set.Status.ErrorMessage = "Exception occurred in GetProducts (username: " + WebserviceUsername + ", password: " + WebservicePassword + ") with message: " + ex.Message;
327
328
329 ex.Data.Add("WebserviceUsername", WebserviceUsername);
330
331 ex.Data.Add("WebservicePassword", WebservicePassword);
332
333 ex.Data.Add("CustomerUsername", CustomerUsername);
334
335 ex.Data.Add("sikbVersion", sikbVersion);
336
337 ex.Data.Add("customerid", customerid);
338
339 ex.Data.Add("languageCode", languageCode);
340
341
342 ExceptionHandler.HandleException(ex);
343
344 #endregion
345
346 }
347
348
349 return set;
350
351 }
352 )))
353
354 |(((
355 POST https:~/~/<URL>/GetProducts HTTP/1.1
356
357 Content-Type: application/x-www-form-urlencoded
358
359 Host: 81.175.89.24
360
361 Content-Length: 179
362
363 Expect: 100-continue
364
365
366 userName=<webservice_username>&password=<Webservice_password>&customerUsername=<customer_username or token>&languageCode=nld&clientId=300&sikbVersion=13.5.0&useZip=True
367 )))
368
369 === Response example ===
370
371 |(((
372 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
373
374 <Response>
375
376 <FileContent> {SIKB FILE in ZIPSTREAM BASE64 format}</FileContent>
377
378 <Status>
379
380 <StatusCode>1</StatusCode>
381
382 <StatusCodeDescription>OK</StatusCodeDescription>
383
384 <ErrorMessage></ErrorMessage>
385
386 </Status></Response>
387 )))
388
389
390
391 = Gebruikersaccount controleren. =
392
393
394 == Oplossing/Design ==
395
396 Bij iedere call gaan we geen username van de klanten meer sturen met een vast webservice username en password voor TerraIndex. Hier willen we ook snel op kunnen controleren of deze wel bestaat.
397
398 WebserviceUsername (string),
399 WebservicePassword (string),
400 CustomerUsername (string)
401
402
403 Hiervoor maken we een Webserice voor ValidCredentials Check:
404
405
406 (% class="table-hover" %)
407 |**Action**|**TerraIndex**| |**Laboratorium**|**Parameters/Message**|**Remarks**|**ResultCodes**
408 |1|Sends a request to the function: ValidCredentials().|=>| |WebserviceUsername (string),
409 WebservicePassword (string),
410 CustomerUsername (string)|We want to skip the Password of the customer, and we use the WebserviceUsername + WebservicePassword for real authentication.|
411 |2| | |Receives the request and checks the combination of WebserviceUsername and WebservicePassword is Ok. Then checks the CustomerUsername is valid.| | |
412 |3| |<=|Sends back a Success of InvalidCredentials|ResultCode (),
413 ErrorMessage (string),| |1 = Success,
414 2 = GeneralError,
415 3 = WrongSIKBVersion,
416 4 = InvalidCredentials,
417 5 = CustomerUsernameInvalid,
418 6 = CustomerUsernameNotValidForCustomerCode
419 7 = FileContentProblem,
420 8 = InvalidOrderId,
421 9 = OrderIdAlreadyApproved
422 10 = PDFNotAvailable
423
424 == Check ValidCredentials (POST) ==
425
426 === Request example ===
427
428 |(((
429 public ValidCredentialsCall.Response ValidCredentials(string WebserviceUsername, string WebservicePassword, string CustomerUsername, string customerid)
430
431 {
432
433 ValidCredentialsCall.Response set = new ValidCredentialsCall.Response();
434
435
436 try
437
438 {
439
440
441 var content = new FormUrlEncodedContent(new[]
442
443 {
444
445 new KeyValuePair<string, string>("userName", WebserviceUsername),
446
447 new KeyValuePair<string, string>("password", WebservicePassword),
448
449 ~/~/new KeyValuePair<string, string>("clientId", customerid),   ~/~/ Optional
450
451 new KeyValuePair<string, string>("customerUsername", CustomerUsername),
452
453 });
454
455
456 HttpResponseMessage response = _HttpClient.PostAsync(_HttpClient.BaseAddress + "/ValidCredentials", content).Result;
457
458 response.EnsureSuccessStatusCode();
459
460 string responseMessage = response.Content.ReadAsStringAsync().Result;
461
462
463 if (string.IsNullOrEmpty(responseMessage))
464
465 {
466
467 throw new Exception("Empty response from: [" + _HttpClient.BaseAddress + " / ValidCredentials" + "]");
468
469 }
470
471 using (var ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseMessage~)~)~)
472
473 {
474
475 XmlSerializer serializer = new XmlSerializer(typeof(ValidCredentialsCall.Response));
476
477 set = (ValidCredentialsCall.Response)serializer.Deserialize(ms);
478
479
480 return set;
481
482 }
483
484
485 }
486
487 catch (Exception ex)
488
489 {
490
491 #region handle exception
492
493
494 set.Status = new BusinessEntities.LabRestService.ValidCredentialsCall.ResponseStatus();
495
496 set.Status.StatusCode = ((int)ResultCodes.GeneralError).ToString();
497
498 set.Status.ErrorMessage = "Exception occurred in GetValidCredentials (username: " + WebserviceUsername + ", with message: " + ex.Message;
499
500
501 ex.Data.Add("WebserviceUsername", WebserviceUsername);
502
503 ex.Data.Add("WebservicePassword", WebservicePassword);
504
505 ex.Data.Add("CustomerUsername", CustomerUsername);
506
507
508 ExceptionHandler.HandleException(ex);
509
510 #endregion
511
512 }
513
514
515 return set;
516
517 }
518 )))
519
520 |(((
521 POST https:~/~/<URL>/ValidCredentials HTTP/1.1
522
523 Content-Type: application/x-www-form-urlencoded
524
525 Host: 81.175.89.24
526
527 Content-Length: 125
528
529 Expect: 100-continue
530
531
532 userName=<webservice_username>&password=<Webservice_password>&clientId=<optional otherwise empty>&customerUsername=<customer_username or token>
533 )))
534
535 === Response example ===
536
537 |(((
538 <?xml version="1.0" encoding="UTF-8" standalone="no"?><Response>
539
540 <Status>
541
542 <StatusCode>1</StatusCode>
543
544 <StatusCodeDescription>OK</StatusCodeDescription>
545
546 <ErrorMessage></ErrorMessage>
547
548 </Status>
549
550 </Response>
551 )))
552
553 = Opdrachten versturen (POST) =
554
555 == Oplossing/Design ==
556
557 Hiervoor maken we een Webserice voor CreateOrder om de opdracht aan te maken.
558 Na de create willen we in de toekomst een overzicht van het laboratorium in bijv. PDF tonen, waarbij de gebruiker de prijzen ziet en kan bevestigen of annuleren.
559 Afhankelijk van de keuze van de gebruiker bij het laboratorium, roept TerraIndex de ApproveOrder of de CancelOrder aan.
560
561 Voor nu gaan we er vanuit dat wij dit niet kunnen, en stuurt TerraIndex needsApprovalIsSupported = false mee. Mocht dit True worden in de toekomst, dan kan het Lab bij het result aangeven of het wel of niet nodig is, in het NeedsApprove veld.
562
563
564 (% class="table-hover" %)
565 |**Action**|**TerraIndex**| |**Laboratorium**|**Parameters/Message**|**Remarks**|**ResultCodes**
566 |1|Sends a request to the function: CreateOrder().|=>| |WebserviceUsername (string),
567 WebservicePassword (string),
568 CustomerUsername (string),
569 FileContent_Base64 (string),
570 UseZipStream/UseZip (bool, default: 'false'),
571 CustomerCode (string),
572 SIKBVersion (string, default: '13.4.0'),
573 needsApprovalIsSupported (bool)|SIKB Version included, so labs can quickly check the version.
574 Besides SIKB 13.4.0, TerraIndex also supports 9.0.0.
575 \\Before sending the SIKB, validate to the XSD!
576 And to the XSLT?
577 \\needsApprovalIsSupported = false; means we dont get PDF with offerte. This will make is faster.
578 needsApprovalIsSupported = true; means lab will check the user setting to send a PDF Offerte back or not. (If the lab can support this.)|
579 |2| | |Receives the request and checks the credentials.| | |
580 |(% colspan="1" %)3|(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)Credentials are valid, the Filecontent is checked on a valid Labassignment. When valid it will be processed and a OrderId is given.|(% colspan="1" %) |(% colspan="1" %)Laboratorium saves the Sample GUIDs if it's SIKB 13 or higher.
581 Otherwise we use the idanlmons unique ID.|(% colspan="1" %)
582 |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)Based on what customer, the order will be approved or the approve needs to be done in laboratorium system.|(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
583 |4| |<=|Sends back a Success with the new OrderId|ResultCode (),
584 ErrorMessage (string),
585 OrderId (string),
586 NeedsApprove (bool),
587 FileContent_Base64 (string),
588 UseZipStream/UseZip (bool, default: 'false'),|In the future labs will send back the PDF with the prices and some checks. To approve or cancel. For the first version this is not required yet and the fileContent remains empty.|1 = Success,
589 2 = GeneralError,
590 3 = WrongSIKBVersion,
591 4 = InvalidCredentials,
592 5 = CustomerUsernameInvalid,
593 6 = CustomerUsernameNotValidForCustomerCode
594 7 = FileContentProblem,
595 8 = InvalidOrderId,
596 9 = OrderIdAlreadyApproved
597 10 = PDFNotAvailable
598 |(% colspan="1" %)6|(% colspan="1" %)Receives the OrderId, and saves it.
599 |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)(((
600 Default for now laboratorium will send:
601 NeedsApprove = False,
602 PDF = Empty,
603 Zipstream = False,
604
605
606 In the future, do something with the PDF and show the PDF to users to Approve or Cancel.
607 This will be done by; NeedsApprove = true.
608 \\If NeedsApprove is False, the order is Processed and can't be changed in TI. Like it is now.
609
610
611 )))|(% colspan="1" %)
612 |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
613 |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
614 |(% colspan="1" %) |(% colspan="1" %)**IN THE FUTURE: APPROVEORDER**|(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
615 |(% colspan="1" %)7|(% colspan="1" %)Sends a request to the function: ApproveOrder().|(% colspan="1" %)=>|(% colspan="1" %) |(% colspan="1" %)WebserviceUsername (string),
616 WebservicePassword (string),
617 CustomerUsername (string),
618 OrderId (string)|(% colspan="1" %) |(% colspan="1" %)
619 |(% colspan="1" %)8|(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)Receives the approve and checks the credentials and the OrderId.|(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
620 |(% colspan="1" %)9|(% colspan="1" %) |(% colspan="1" %)<=|(% colspan="1" %)Sends back a Success with the new CertificateNr|(% colspan="1" %)ResultCode (),
621 ErrorMessage (string),
622 CertificateNr (string)|(% colspan="1" %)This process takes too long at some labs. Maybe this won't be workable...so maybe the CertificateNr return won't be possible. In this case, leave the CertificateNr empty. TerraIndex will read it from GetOrderStatus calls.|(% colspan="1" %)1 = Success,
623 2 = GeneralError,
624 3 = WrongSIKBVersion,
625 4 = InvalidCredentials,
626 5 = CustomerUsernameInvalid,
627 6 = CustomerUsernameNotValidForCustomerCode
628 7 = FileContentProblem,
629 8 = InvalidOrderId,
630 9 = OrderIdAlreadyApproved
631 10 = PDFNotAvailable
632 |(% colspan="1" %)10|(% colspan="1" %)Receives the CerificateNr and saves it.|(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
633 |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
634 |(% colspan="1" %) |(% colspan="1" %)**IN THE FUTURE: CANCELORDER**|(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
635 |7|Sends a request to the function: CancelOrder().|=>| |WebserviceUsername (string),
636 WebservicePassword (string),
637 CustomerUsername (string),
638 OrderId (string)| |
639 |8| | |Receives the cancel and checks the credentials and the OrderId.| | |
640 |9| |<=|Sends back a Success |ResultCode (),
641 ErrorMessage (string)| |1 = Success,
642 2 = GeneralError,
643 3 = WrongSIKBVersion,
644 4 = InvalidCredentials,
645 5 = CustomerUsernameInvalid,
646 6 = CustomerUsernameNotValidForCustomerCode
647 7 = FileContentProblem,
648 8 = InvalidOrderId,
649 9 = OrderIdAlreadyApproved
650 10 = PDFNotAvailable
651 |10|Removes the OrderId and the IsSend to False| | | |If OrderIsAleadyApproved, set the values to Approved and keep the OrderId and IsSend.|
652 |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %) |(% colspan="1" %)
653
654 == Create Order ==
655
656 === Request example ===
657
658 |(((
659 public CreateOrderResponse.Response SendLabAssignment(string WebserviceUsername, string WebservicePassword, string CustomerUsername, string customerid, string sikbVersion, string assignmentXML, string languageCode, bool needsApprovalIsSupported = false)
660
661 {
662
663 CreateOrderResponse.Response set = new CreateOrderResponse.Response();
664
665
666 try
667
668 {
669
670 bool useZipstream = true;
671
672
673 MultipartFormDataContent content = new MultipartFormDataContent();
674
675
676 ~/~/Add Formdata
677
678 var formDataDictionary = new[]
679
680 {
681
682 new KeyValuePair<string, string>("userName", WebserviceUsername),
683
684 new KeyValuePair<string, string>("password", WebservicePassword),
685
686 new KeyValuePair<string, string>("customerUserName", CustomerUsername),
687
688 new KeyValuePair<string, string>("clientId", customerid),
689
690 new KeyValuePair<string, string>("sikbVersion", sikbVersion),
691
692 new KeyValuePair<string, string>("languageCode", languageCode),
693
694 new KeyValuePair<string, string>("useZip", useZipstream.ToString() ),
695
696 new KeyValuePair<string, string>("needsApprovalIsSupported", needsApprovalIsSupported.ToString() ),
697
698 ~/~/new KeyValuePair<string, string>("orderXml", ZipStreamHelper.CompressToBase64String(assignmentXML)),
699
700 ~/~/new KeyValuePair<string, string>("orderXml", assignmentXML),
701
702 };              
703
704 foreach (var item in formDataDictionary)
705
706 {
707
708 content.Add(new StringContent(item.Value), $"\"{item.Key}\"");
709
710 }
711
712
713 string filexml = string.Empty;
714
715 if (useZipstream)
716
717 {
718
719 filexml = ZipStreamHelper.CompressToBase64String(assignmentXML);
720
721 }
722
723 else
724
725 {
726
727 filexml = assignmentXML;
728
729 }
730
731
732 ~/~/Add filecontent
733
734 var fileContent = new ByteArrayContent(ZipStreamHelper.stringToByteArray(filexml));
735
736 fileContent.Headers.ContentDisposition =
737
738 new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") ~/~/<- 'form-data' instead of 'attachment'
739
740 {
741
742 Name = "\"orderXml\"", ~/~/ \" is needed so the message contains the quotes, wihtout it will fail
743
744 FileName = "\"VivaTerraIndexAssignment.xml\""
745
746 };
747
748 fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/xml");              
749
750 content.Add(fileContent);
751
752
753 ~/~/Start sending
754
755
756 HttpResponseMessage response = _HttpClient.PostAsync(_HttpClient.BaseAddress + "/CreateOrder", content).Result;
757
758 response.EnsureSuccessStatusCode();
759
760 string responseMessage = response.Content.ReadAsStringAsync().Result;
761
762
763 if (string.IsNullOrEmpty(responseMessage))
764
765 {
766
767 throw new Exception("Empty response from: [" + _HttpClient.BaseAddress + " /CreateOrder" + "]");
768
769 }
770
771 using (var ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseMessage~)~)~)
772
773 {
774
775 XmlSerializer serializer = new XmlSerializer(typeof(CreateOrderResponse.Response));
776
777 set = (CreateOrderResponse.Response)serializer.Deserialize(ms);
778
779 }
780
781
782 ~/~/Can contain a PDf with price information
783
784 if (set.UseZip && !string.IsNullOrEmpty(set.FileContent))
785
786 {
787
788 ~/~/convert from base64 string back to normal
789
790 set.FileContent = ZipStreamHelper.DecompressBase64StringToString(set.FileContent);                  
791
792 }
793
794
795 }
796
797 catch (Exception ex)
798
799 {
800
801 #region handle exception
802
803
804 set.Status = new BusinessEntities.LabRestService.CreateOrderResponse.ResponseStatus();
805
806 set.Status.StatusCode = ((int)ResultCodes.GeneralError).ToString();
807
808 set.Status.ErrorMessage = "Exception occurred in CreateOrder (username: " + WebserviceUsername + ") with message: " + ex.Message;
809
810
811 ex.Data.Add("WebserviceUsername", WebserviceUsername);
812
813 ex.Data.Add("WebservicePassword", WebservicePassword);
814
815 ex.Data.Add("CustomerUsername", CustomerUsername);
816
817 ex.Data.Add("sikbVersion", sikbVersion);
818
819 ex.Data.Add("customerid", customerid);
820
821
822 ExceptionHandler.HandleException(ex);
823
824 #endregion
825
826 }
827
828
829 return set;
830
831 }
832 )))
833
834 |(((
835 POST https:~/~/<URL>/CreateOrder HTTP/1.1
836
837 Content-Type: multipart/form-data; boundary="28a3e130-70c9-4a1a-b544-a802a1ade6ca"
838
839 Host: 81.175.89.24
840
841 Content-Length: 5010
842
843 Expect: 100-continue
844
845
846 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
847
848 Content-Type: text/plain; charset=utf-8
849
850 Content-Disposition: form-data; name="userName"
851
852
853 <Webservice_Username>
854
855 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
856
857 Content-Type: text/plain; charset=utf-8
858
859 Content-Disposition: form-data; name="password"
860
861
862 <Webservice_Password>
863
864 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
865
866 Content-Type: text/plain; charset=utf-8
867
868 Content-Disposition: form-data; name="customerUserName"
869
870
871 <Customer_Username or token>
872
873 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
874
875 Content-Type: text/plain; charset=utf-8
876
877 Content-Disposition: form-data; name="clientId"
878
879
880 300
881
882 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
883
884 Content-Type: text/plain; charset=utf-8
885
886 Content-Disposition: form-data; name="sikbVersion"
887
888
889 13.4.0
890
891 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
892
893 Content-Type: text/plain; charset=utf-8
894
895 Content-Disposition: form-data; name="languageCode"
896
897
898 nld
899
900 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
901
902 Content-Type: text/plain; charset=utf-8
903
904 Content-Disposition: form-data; name="useZip"
905
906
907 True
908
909 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
910
911 Content-Type: text/plain; charset=utf-8
912
913 Content-Disposition: form-data; name="needsApprovalIsSupported"
914
915
916 False
917
918 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca
919
920 Content-Disposition: form-data; name="orderXml"; filename="VivaTerraIndexAssignment.xml"
921
922 Content-Type: application/xml
923
924
925 <SIKB File in Zip stream Base64  encoding>
926
927 ~-~-28a3e130-70c9-4a1a-b544-a802a1ade6ca~-~-
928 )))
929
930 === Response example ===
931
932 |(((
933 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
934
935 <Response>
936
937 <OrderId>7113828</OrderId>
938
939 <NeedsApproval>True</NeedsApproval>
940
941 <FileContent></FileContent>
942
943 <Status>
944
945 <StatusCode>1</StatusCode>
946
947 <StatusCodeDescription>OK</StatusCodeDescription>
948
949 <ErrorMessage></ErrorMessage>
950
951 </Status></Response>
952 )))
953
954
955
956 = Get Order status and Results =
957
958 == Oplossing/Design ==
959
960 TerraIndex gaat opvragen per licentie, welke resultaten en klaar staan. Deze worden opgevraagd als de nieuwste wijzigingen nieuwer zijn dan de laatste keer checken. Zo downloaden we nooit onnodig teveel en is het altijd nogmaals op te vragen.
961
962
963 (% class="table-hover" %)
964 |Action|TerraIndex| |Laboratorium|Parameters/Message|Remarks|ResultCodes
965 |1|Sends a request to the function: GetCustomers().|=>| |WebserviceUsername (string), 
966 WebservicePassword (string),
967 CustomerUsername (string)|We want to skip the Password of the customer, and we introduce the WebserviceUsername + WebservicePassword.|
968 |2| | |Receives the request and check the customers this username and searches the dateLastChanged for this Customer.| | |
969 |3| |<=|Sends back the list of customers with the lastChangedTimestamp|ResultCode (),
970 ErrorMessage (string),
971 List<customer> , Customer:
972 CustomerCode (string),
973 CustomerName (string),
974 LabID (int),
975 LabName (string),
976 ChangedTimeStamp (DateTime)|We receive the dateTimestamp instead of sending it, so we always get the full list and we are also able to delete customercodes.|1 = Success,
977 2 = GeneralError,
978 3 = WrongSIKBVersion,
979 4 = InvalidCredentials,
980 5 = CustomerUsernameInvalid,
981 6 = CustomerUsernameNotValidForCustomerCode
982 7 = FileContentProblem,
983 8 = InvalidOrderId,
984 9 = OrderIdAlreadyApproved
985 10 = PDFNotAvailable
986 |4|Receives the list of Customers. Read the Timestamp this Customer is last checked for Results/Statuses.| | | | |
987 |5|Send for each Customer a  call to retreive all orders statuses changes since a certain timestamp.
988 Function: GetOrderStatuses()|=>| |WebserviceUsername (string), 
989 WebservicePassword (string),
990 CustomerUsername (string),
991 CustomerCode (string),
992 LastCheckedTimestamp (DateTime)|TerraIndex keeps track of the last check timestamp for each license.|
993 |6| | |Receives the request and check the orders that are changed since the timestamp for this Customer.| | |
994 |7| |<=|Sends back the list of orders with the status and lastChangedTimestamp|ResultCode (),
995 ErrorMessage (string),
996 OrderID (string),
997 LabassignmentGUID (GUID),
998 CertificateNumber (string)
999 OrderStatusSIKB (int),
1000 Delayed (boolean),
1001 ExpectedTimeStamp (DateTime),|OrderStatusSIKB is the SIKB Labassignment status.
1002 \\Delayed is a boolean to tell the customer a order will be later ready then expected. The ExpectedTimestamp.
1003 If Delayed for the firsttime, TerraIndex can send a notification to the users and show a different layout.
1004 \\LabassignmentGUID is filled to support also Labassignments that are not from TerraIndex Ordered.|1 = Success,
1005 2 = GeneralError,
1006 3 = WrongSIKBVersion,
1007 4 = InvalidCredentials,
1008 5 = CustomerUsernameInvalid,
1009 6 = CustomerUsernameNotValidForCustomerCode
1010 7 = FileContentProblem,
1011 8 = InvalidOrderId,
1012 9 = OrderIdAlreadyApproved
1013 10 = PDFNotAvailable
1014 |8|Receives the list of Orders with status.
1015 Update the CertificateNr if this is not already present in the labassignment. | | | |CertifcateNumber could be new here, if the lab wasn't able to fill it directly at the ApproveOrder.|
1016 |9|Send for each Order a call to retreive all results.
1017 Function: GetOrderResults()|=>| |WebserviceUsername (string), 
1018 WebservicePassword (string),
1019 CustomerUsername (string),
1020 CustomerCode (string),
1021 OrderID (string),
1022 SIKBVersion (string, default: '13.4.0')|Besides SIKB 13.4.0, TerraIndex also supports 9.0.0/8.0.0 etc.|
1023 |10| | |Receives the request and creates a SIKB results file based on the version that is requested.| | |
1024 |11| |<=|Sends back the results of the orders.|ResultCode (),
1025 ErrorMessage (string),
1026 OrderId (string),
1027 LabassignmentGUID (GUID),
1028 FileContent_Base64 (string),
1029 UseZipStream/UseZip (bool, default: 'false'),| |1 = Success,
1030 2 = GeneralError,
1031 3 = WrongSIKBVersion,
1032 4 = InvalidCredentials,
1033 5 = CustomerUsernameInvalid,
1034 6 = CustomerUsernameNotValidForCustomerCode
1035 7 = FileContentProblem,
1036 8 = InvalidOrderId,
1037 9 = OrderIdAlreadyApproved
1038 10 = PDFNotAvailable
1039 |12|Receives the results and imports all results.| | | |(((
1040 Import will be done to corresponding samples based on:
1041
1042 * Find Project by ProjectGUID (as provided in the labassignment)
1043 * Find Project by ProjectCode (as provided in the Labassignment)
1044 * Find Project and Labassignment by LabassignmentGUID (as provided in the Labassignment)
1045 * Find Project (only if Project is not found yet) and Samples based on SampleGUID (as provided in the Labassignment) .
1046 Sample GUIDs that are send to the lab in the labassignment version SIKB 13 or higher are required in the results for labassignment.
1047 For lower version Labassignments the lab should return the 'old' idanlmons as SampleGUID in the XML.
1048 * Find Samples (only if Project is already found ) by SampleName
1049
1050 What is imported?
1051
1052 * If Sample is found, the results in the XML are always all updated and/or inserted.
1053 * If Project is found, but the sample is not; The Sample and the results are inserted as new Sample. (If watersample; fake filtertube and fake measurementpoints are created)
1054 )))|
1055 |13|If OrderStatus is 'Completed/Reported' (SIKBID: 5)
1056 Request the PDF certificate.
1057 Function: GetOrderPDF()|=>| |WebserviceUsername (string), 
1058 WebservicePassword (string),
1059 CustomerUsername (string),
1060 CustomerCode (string),
1061 OrderID (string),| |
1062 |14| | |Receives the request and creates the PDF for the Order.| | |
1063 |15| |<=|Sends back the PDF of the order.|ResultCode (),
1064 ErrorMessage (string),
1065 OrderId (string),
1066 LabassignmentGUID (GUID),
1067 FileContent_Base64 (string),
1068 UseZipStream/UseZip (bool, default: 'false'),|If the PDF is not available yet, please give the resultcode: PDFNotAvailable.|1 = Success,
1069 2 = GeneralError,
1070 3 = WrongSIKBVersion,
1071 4 = InvalidCredentials,
1072 5 = CustomerUsernameInvalid,
1073 6 = CustomerUsernameNotValidForCustomerCode
1074 7 = FileContentProblem,
1075 8 = InvalidOrderId,
1076 9 = OrderIdAlreadyApproved
1077 10 = PDFNotAvailable
1078 |12|Receives the PDF and stores it for reporting and downloading.| | | | |
1079
1080 =
1081 Customer wants to see real time information about the status in the interface =
1082
1083 == Oplossing/Design ==
1084
1085 Om in de interface van TerraIndex altijd up to date informatie te tonen als een gebruiker een labopdracht opent om de status te zien, hergebruiken we een deel van de GetOrderStatus, maar dan met specifiek een OrderID.
1086
1087 ..NOT SUPPORTED YET...
1088
1089 (% class="table-hover" %)
1090 |(% colspan="1" %)Action|(% colspan="1" %)TerraIndex|(% colspan="1" %) |(% colspan="1" %)Laboratorium|(% colspan="1" %)Parameters/Message|(% colspan="1" %)Remarks|(% colspan="1" %)ResultCodes
1091 |1|Request the Order status for a single Order/Labassignment.
1092 Function: GetOrderStatus()|=>| |WebserviceUsername (string), 
1093 WebservicePassword (string),
1094 CustomerUsername (string),
1095 CustomerCode (string),
1096 OrderID (string),| |
1097 |2| | |Receives the request and gets the status for the Order.| | |
1098 |3| |<=|Sends back the status of the order.|ResultCode (),
1099 ErrorMessage (string),
1100 OrderID (string),
1101 LabassignmentGUID (GUID),
1102 CertificateNumber (string)
1103 OrderStatusSIKB (int),
1104 Delayed (boolean),
1105 ExpectedTimeStamp (DateTime),|OrderStatusSIKB is the SIKB Labassignment status.
1106 \\Delayed is a boolean to tell the customer a order will be later ready then expected. The ExpectedTimestamp.
1107 If Delayed for the firsttime, TerraIndex can send a notification to the users and show a different layout.
1108 \\LabassignmentGUID is filled to support also Labassignments that are not from TerraIndex Ordered.|1 = Success,
1109 2 = GeneralError,
1110 3 = WrongSIKBVersion,
1111 4 = InvalidCredentials,
1112 5 = CustomerUsernameInvalid,
1113 6 = CustomerUsernameNotValidForCustomerCode
1114 7 = FileContentProblem,
1115 8 = InvalidOrderId,
1116 9 = OrderIdAlreadyApproved
1117 10 = PDFNotAvailable
1118 |4|Receives the status and shows in the interface the updated info.
1119 Update the CertificateNr if this is not already present in the labassignment. | | | |CertifcateNumber could be new here, if the lab wasn't able to fill it directly at the ApproveOrder.|
1120
1121
1122
1123
1124
1125
1126