3. Retrieving latest reports
A typical integration scenario is, that you have to retrieve all the final reports of inspections to e.g. store them in some special document management system. This may even be a legal requirement. There are two approaches for this.
- You can query the changes of tasks until a task is marked as completed and has a sent date. At this point in time, you can query all the reports of this task/inspection and download each file individually.
- The simpler approach is to query the changes of reports themselves.
In any case, what you need to take care of is to check that the report is not a draft and that it has been created successfully.
This can be done by inspecting the isDraft
and reportState
properties of the report.
- A report that has
isDraft
set totrue
is just a draft report that was created by the user during the inspection to check what the report will look like. - Any other
reportState
than3
means that the report was not created successfully and you should not download it.
Reports do have their own set of states.
0
... means pending or awaiting creation1
... once the Portal starts generating the report, the state is set to1
which means generating2
... in case something goes wrong - like there is an error in the report template - the state is set to2
which means error3
... or if all goes well and the report was generated successfully, the state will be3
which means generated
1st approach: Downloading reports of completed tasks/inspectionsβ
This first approach is advisable in case you need to additionally update some metadata on the tasks in your legacy system. While you are already querying the changes of tasks, you can also check if the task is completed and has a sent date to determine if there are reports to be downloaded.
The first thing to do would be to get the latest changed tasks.
To get an in-depth understanding of this API, please read this walkthrough.
GET https://dev.iclportal.com/api/services/custom/externalTask/GetChanges?changeToken=AAAAAAAFpYA HTTP/1.1
Accept: application/json
Authorization: Bearer HwBUGEn1p9S5BJi6iM.....
AAAAAAAFpYA
is a ficticious change token. You need to replace it with the latest change token you received from the previous call or omit it
This will give you the last change tasks. Now, assuming that one of the tasks has the state completed and a sent date:
{
"result": {
"results": [
{
"id": "5bb89fe4-25dd-4014-b00e-c3ed05c15213",
"inspectionId": "6603837e-2d0d-4b3b-9264-99867c4151a8",
"externalId": "TSK___000001",
"title": "Task 000000",
"workbookId": "baf7b34d-825a-443b-bf5e-928ff83d9c2e",
"workbookTitle": "test iWorkbook",
"workbookVersionCode": 52,
"assignedUserId": 4,
"assignedUserName": "antoine gadget",
"description": null,
"startDate": null,
"dueDate": null,
"state": 3, // this is the state "completed"
"isSelfAssignable": true,
"workAreaId": "6058f602-f55b-45b2-90b2-9081869f7774",
"workAreaTitle": "test",
"isPublished": true,
"actualStart": "2022-10-18T13:16:23.583Z",
"actualEnd": "2022-10-18T14:15:23.583Z", // the inspector completed this task
"sentDate": "2022-10-18T16:20:00.583Z", // and the sent date is set meaning all required reports were generated
"hasTask": true,
"lastModificationTime": "2022-10-21T13:16:23.583Z",
"inspectedItems": null,
"isDeleted": false
},
... many many more... (500 total)
],
"nextChangeToken": "AAAAAAAFpYA",
"nextLink": "https://dev.iclportal.com/api/services/custom/externalTask/GetChanges?changeToken=AAAAAAAFpYA"
},
"targetUrl": null,
"success": true,
"error": null,
"unAuthorizedRequest": false,
"__abp": true
}
Now, you know that you can query the reports of this task. To do so, first you need to get all the reports of this task/inspection:
GET https://dev.iclportal.com/api/services/app/reports/getofinspection?inspectionId=6603837e-2d0d-4b3b-9264-99867c4151a8
Authorization: Bearer HwBUGEn1p9S5BJi6iM.....
inspectionid
Note, that you need the inspectionid
and not the externalid
for this endpoint
This will give you a list of all the reports of this task/inspection
{
"result": {
"results": [
{
"id": "5576222e-6936-41e5-adc2-468ee5022e35",
"isDraft": false, // this is a final report
"reportState": 3, // 3 means "created successfully"
"fileName": "003ZP1332-2022-3_WORD.docx",
"mimeType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"recipients": null,
"error": null,
"created": "2022-10-18T13:28:09.48Z",
"workAreaId": "f46628b0-8eb2-4db3-b142-e77c23572400"
},
{
"id": "472ec6d5-3a8f-45d0-812c-be801de8dd9a",
"isDraft": false, // this is a final report
"reportState": 3, // 3 means "created successfully"
"fileName": "003ZP1332-2022-3.pdf",
"mimeType": "application/pdf",
"recipients": "optiqser@opti-q.com,office@democorp.com",
"error": null,
"created": "2022-10-18T13:27:48.997Z",
"workAreaId": "f46628b0-8eb2-4db3-b142-e77c23572400"
}
],
"__count": 2
},
"targetUrl": null,
"success": true,
"error": null,
"unAuthorizedRequest": false,
"__abp": true
}
As you can see, the results inform you about when the report was created and what the report is (pdf, word, etc.).
What is more important, though, is that the reportState
is 3.
The final step involves downloading each report using its id
using the reports get API.
GET https://dev.iclportal.com/api/reports/get/5576222e-6936-41e5-adc2-468ee5022e35
Authorization: Bearer HwBUGEn1p9S5BJi6iM.....
The response will be the file with a Content-Disposition
header set to attachment; filename="003ZP1332-2022-3_WORD.docx"
.
2nd approach: Downloading all completed reportsβ
This approach uses the reports getchanges API.
For you first call, you can omit the changeToken
parameter.
GET https://dev.iclportal.com/api/services/custom/externalReports/GetChanges HTTP/1.1
Accept: application/json
Authorization: Bearer HwBUGEn1p9S5BJi6iM.....
Response gives us the reports (as expected) but includes a nextChangeToken
and nextLink
that can be used to get the next 500 changed reports.
{
"result": {
"results": [
{
"id": "4b2c2e24-52b6-4f3f-8efa-3fd7b15c3e0c",
"reportState": 3, // generated successfully
"error": null,
"isDraft": false, // not a draft
"fileName": null,
"mimeType": null,
"recipients": "optiqser@opti-q.com,s.p@opti-q.com",
"taskTitle": null,
"taskId": null,
"inspectionId": "a4da0ea9-e567-4c15-8c8f-25526b17d1a4",
"taskExternalId": null,
"inspectionTitle": "Brandschutz-Kontrolle 13.08.2021",
"workAreaTitle": "Brandschutz Test",
"workbookTitle": "Brandschutz-Kontrolle",
"creationTime": "2021-08-13T11:58:39.72Z",
"created": "2021-08-13T11:59:50.637Z",
"inspectionCompletedDate": "2021-08-13T11:58:13.533Z",
"inspectionSentDate": "2021-08-13T12:00:51.95Z",
"workAreaId": "c9518bd5-016f-4030-9937-86e5c3a1b97f",
"isDeleted": false, // not deleted
"deletionTime": null
},
{
"id": "9ab5d5b7-d692-4600-a82b-c0e1e271c4d7",
"reportState": 3,
"error": null,
"isDraft": false,
"fileName": null,
"mimeType": null,
"recipients": null,
"taskTitle": null,
"taskId": null,
"inspectionId": "a4da0ea9-e567-4c15-8c8f-25526b17d1a4",
"taskExternalId": null,
"inspectionTitle": "Brandschutz-Kontrolle 13.08.2021",
"workAreaTitle": "Brandschutz Test",
"workbookTitle": "Brandschutz-Kontrolle",
"creationTime": "2021-08-13T11:59:58.31Z",
"created": "2021-08-13T12:00:25.94Z",
"inspectionCompletedDate": "2021-08-13T11:58:13.533Z",
"inspectionSentDate": "2021-08-13T12:00:51.95Z",
"workAreaId": "c9518bd5-016f-4030-9937-86e5c3a1b97f",
"isDeleted": false, // this also gives you deleted reports
"deletionTime": null
},
... many many more... (500 total)
],
"nextChangeToken": "AAAAAAAFpYA",
"nextLink": "https://dev.iclportal.com/api/services/custom/externalReports/GetChanges?changeToken=AAAAAAAFpYA"
},
"targetUrl": null,
"success": true,
"error": null,
"unAuthorizedRequest": false,
"__abp": true
}
So to get the next 500 changed reports, you can either just use the nextLink
value or call the API with nextChangeToken
like the following:
GET https://dev.iclportal.com/api/services/custom/externalReports/GetChanges?changeToken=AAAAAAAFpYA HTTP/1.1
Accept: application/json
Authorization: Bearer HwBUGEn1p9S5BJi6iM.....
As there are no more changes, the system simply returns the latest change available, which is usually the very same change token we just used in the request.
However, you can use this mechanism to get straight to the last page of changed reports by using the highest possible change token __________8
This comes in handy, if you only want to start for getting changes from now on and do not wish to go through all the historical changes.
Then, for each report that
- is not deleted (i.e.
isDeleted
isfalse
) - was generated successfully (i.e.
reportState
is3
) - and is not a draft report (i.e.
isDraft
isfalse
) you can download the report using the reports get API using itsid
.
GET https://dev.iclportal.com/api/reports/get/4b2c2e24-52b6-4f3f-8efa-3fd7b15c3e0c
Authorization: Bearer HwBUGEn1p9S5BJi6iM.....
The response will be the file with a Content-Disposition
header set to attachment; filename="003ZP1332-2022-3_WORD.docx"
.