Berichte
Um die für eine bestimmte Inspektion erstellten Berichte herunterzuladen, können die folgenden REST-Dienste verwendet werden. Endpunkte:
- /api/services/custom/externalReports (Abfragen von Berichten und Abrufen geänderter Berichte)
- /api/reports (Herunterladen von Berichten)
- /api/services/app/reports (Berichte einer Inspektion; wird vom Portal selbst verwendet und ist nicht in Swagger aufgeführt)
1. Abfrage von Berichten
Sobald ein Inspektor eine Inspektion abgeschlossen oder einen Berichtsentwurf erstellt hat, kann die Liste der Berichte abgerufen werden.
Url: /getall
HTTP-Methode: GET
Beispiel:
GET https://dev.iclportal.com/api/services/custom/externalReports/GetAll HTTP/1.1
{
"results":[
{
"id": "e4b102ca-f691-4c6a-8e4a-0001e5b94eef",
"reportState": 3,
"error": null,
"isDraft": false,
"fileName": "TheActualFilename.pdf",
"mimeType": "application/pdf",
"recipients": "",
"taskTitle": null,
"taskId": null,
"inspectionId": "0af1e86c-a244-4ac9-9f4e-78b856b1f240",
"taskExternalId": null,
"inspectionTitle": "Brandschutz",
"workAreaTitle": "Auftrag",
"workbookTitle": "✅ Auftragsbearbeitung",
"workbookDefinitionId": "89ec0d17-3131-4bea-bed0-5ac2d72a8ba9",
"creationTime": "2026-03-26T10:12:20.89Z",
"created": "2026-03-26T10:12:23.673Z",
"inspectionCompletedDate": "2026-03-26T10:12:10.337Z",
"inspectionSentDate": "2026-03-26T10:12:23.673Z",
"workAreaId": "7dbb473b-8c4c-474d-9219-a577d14663fc"
}
],
"__count":1
}
Beispiel 2 – Abrufen einer Liste von 10 Berichten, die seit einem bestimmten Zeitpunkt erfolgreich erstellt wurden:
GET https://dev.iclportal.com/api/services/custom/externalReports/GetAll?$filter=Created+ge+datetime%272016-03-15T00:00:00%27&$inlinecount=allpages&$top=10 HTTP/1.1
{
"results":[
{
"id": "e4b102ca-f691-4c6a-8e4a-0001e5b94eef",
"reportState": 3,
"error": null,
"isDraft": false,
"fileName": "TheActualFilename.pdf",
"mimeType": "application/pdf",
"recipients": "",
"taskTitle": null,
"taskId": null,
"inspectionId": "0af1e86c-a244-4ac9-9f4e-78b856b1f240",
"taskExternalId": null,
"inspectionTitle": "Brandschutz",
"workAreaTitle": "Auftrag",
"workbookTitle": "✅ Auftragsbearbeitung",
"workbookDefinitionId": "89ec0d17-3131-4bea-bed0-5ac2d72a8ba9",
"creationTime": "2026-03-26T10:12:20.89Z",
"created": "2026-03-26T10:12:23.673Z",
"inspectionCompletedDate": "2026-03-26T10:12:10.337Z",
"inspectionSentDate": "2026-03-26T10:12:23.673Z",
"workAreaId": "7dbb473b-8c4c-474d-9219-a577d14663fc"
}
],
"__count":1
}
| Name | Typ | Beschreibung |
|---|---|---|
| id | string | Die eindeutige Identität eines Berichts. Hinweis: Jedes Mal, wenn ein Bericht neu erstellt wird, wird ein neuer Datensatz für ihn angelegt. Daher ändert sich auch die ID. |
| isDraft | boolean | Wenn true, bedeutet dies, dass es sich nicht um einen endgültigen Bericht handelt, sondern um einen Berichtsentwurf, der vor Abschluss einer Inspektion erstellt wurde, um eine Vorschau des Dokuments zu erhalten |
| reportState | number | Gibt an, in welchem Zustand sich ein Bericht befindet. Kann 0..ausstehend, 1..wird generiert, 2..fehlgeschlagen, 3..generiert sein. |
| fileName | string | Der Dateiname |
| mimeType | string | Der Mime-Typ |
| recipients | string | Kommagetrennte Liste aller E-Mail-Adressen, an die dieser Bericht gesendet wurde. |
| error | string | Falls der Berichtsstatus 2..fehlgeschlagen ist, wird in diesem Feld die Fehlermeldung angezeigt. |
| creationTime | date | Der Zeitpunkt, zu dem der Datensatz für diesen Bericht erstellt wurde. Hinweis: Dies geschieht in der App, sodass die Verwendung dieses Feldes zum Filtern von Berichten zu fehlenden Daten führen kann, da diese Berichte möglicherweise noch nicht synchronisiert wurden. |
| created | date | Der Zeitpunkt, zu dem der Bericht auf dem Server erstellt wurde. Dieses Feld kann für Abfragen von inkrementellen Änderungen verwendet werden. |
| inspectionCompletedDate | date | Der Zeitpunkt, an dem der Benutzer die Inspektion in der App abgeschlossen hat. Hinweis: Dies geschieht in der App, sodass die Verwendung dieses Feldes zum Filtern von Berichten zu fehlenden Daten führen kann, da diese Berichte möglicherweise noch nicht synchronisiert wurden. |
| inspectionSentDate | date | Der Zeitpunkt, an dem die App festgestellt hat, dass alle Daten an den Server übertragen und alle Abschlussberichte erfolgreich erstellt wurden. Hinweis: Dies geschieht in der App, sodass die Verwendung dieser Angabe zum Filtern von Berichten zu fehlenden Daten führen kann, da diese Berichte möglicherweise noch nicht synchronisiert wurden. |
| workAreaId | string | Die eindeutige Identität des Teams, in dem dieser Bericht (und seine übergeordnete Inspektion) erstellt wurde. |
| taskTitle | string | Der Titel der zugehörigen Aufgabe. |
| taskId | string | Die eindeutige Identität der zugehörigen Aufgabe. |
| taskExternalId | string | Die externe Identität der zugehörigen Aufgabe. |
| inspectionId | string | Die eindeutige Identität der Inspektion, zu der der Bericht gehört. |
| inspectionTitle | string | Der Titel der Inspektion. |
| workAreaTitle | string | Der Titel des Teams. |
| workbookTitle | string | Der Titel des Workbooks. |
| workbookDefinitionId | string | Die eindeutige Identität der Workbookdefinition. |
Der Prozess zur Erstellung der Berichte läuft folgendermaßen ab:
- Der Benutzer schließt die Inspektion in der App ab. (
inspectionCompletedDate) - Daher werden die Datensätze für die Abschlussberichte erstellt (
creationTime) - Der Server erstellt die Berichte und legt ihr Erstellungsdatum fest. (
created) - Wenn die App die Bestätigung erhält, dass alle Berichte erstellt wurden, kennzeichnet sie die Inspektion als gesendet (
inspectionSentDate) Dies zeigt, dass diese Datumsfelder immer die folgende Beziehung haben:inspectionCompletedDate < creationTime < created < inspectionSentDate
Parameter: Dies ist ein ODATA 3.0 Endpunkt, mit dem Sie die Berichte im System abfragen können.
Die Ergebnisse werden in Seiten zu je 500 Berichten geliefert. Gibt es weitere Ergebnisse, enthält die Antwort einen __next-Link auf die nächste Seite.
Mit der Berechtigung Reports.View erhalten Sie alle Berichte. Andernfalls erhalten Sie nur die Berichte von Teams, in denen Sie diese Berechtigung haben, von Inspektionen, die Sie erstellt haben, und von Aufgaben, die Ihnen zugewiesen sind.
Sie können alle Attribute der zurückgegebenen json-Objekte verwenden, um eine Abfrage zu erstellen. Aufgrund der ODATA-Spezifikation müssen Sie sie jedoch in der Abfrage in Großbuchstaben schreiben. Da dies eine Konvention in JSON und der JavaScript-Welt ist, werden unsere Ergebnisse mit klein geschriebenen Attributnamen zurückgegeben.
Beispiel: Sie erhalten einen Bericht wie:
{"workAreaTitle":"Vienna Inspectors", …}
Wie Sie sehen können, beginnt das Attribut "workAreaTitle" mit einem Kleinbuchstaben.
Wenn Sie jedoch den ODATA-Endpunkt mit "workAreaTitle" abfragen, müssen Sie den ersten Buchstaben in Großbuchstaben schreiben:
/getall?$filter=WorkAreaTitle+eq+….
"WorkArea" ist unser interner Name für "Team".
2. Abrufen der Liste der Berichte für eine Inspektion
Sobald ein Inspektor eine Inspektion abgeschlossen oder einen Berichtsentwurf erstellt hat, kann die Liste der Berichte abgerufen werden.
Url: /getofinspection
HTTP-Methode: GET
Beispiel:
GET https://dev.iclportal.com/api/services/app/reports/getofinspection?inspectionId=<uniqueid> HTTP/1.1
| Name | Typ | Erforderlich? | Beschreibung |
|---|---|---|---|
| inspectionId | string | Erforderlich | Die eindeutige Identität der Inspektion, zu der die Berichte gehören. (Sie erhalten sie z.B. aus der inspectionId eines Berichts oder einer Aufgabe) |
Der Server antwortet mit einem 200 OK, das im Antwortkörper ein Objekt mit einem results-Array (und der Gesamtanzahl __count) enthält. Jeder Eintrag des Arrays enthält die folgenden Felder:
| Name | Typ | Beschreibung |
|---|---|---|
| id | string | Die eindeutige ID des Berichts. |
| isDraft | boolean | True, wenn dies ein Berichtsentwurf ist, der jederzeit gelöscht werden kann. False, wenn es sich um einen endgültigen Bericht handelt. |
| reportState | enumeration | Der aktuelle Status, in dem sich dieser bestimmte Bericht befindet: Pending = 0, // wartet darauf, generiert zu werden Generating = 1, // wird gerade generiert Failed = 2, // konnte den Bericht nicht generieren Generated = 3, // der Bericht ist vollständig und kann abgerufen werden |
| fileName | string | Der tatsächliche Dateiname dieses Berichts. |
| mimeType | string | Der Mimetyp der Berichtsdatei. |
| recipients | string | Die Liste der E-Mail-Empfänger, an die dieser Bericht gesendet wird/wurde. |
| error | string | Falls bei der Erstellung des Berichts ein Fehler aufgetreten ist, enthält dieses Feld die Fehlermeldung. |
| created | date | Das Datum und die Uhrzeit, zu der dieser Bericht erstellt wurde. |
| durationInSeconds | number | Wie lange die Erstellung des Berichts gedauert hat. |
| workAreaId | string | Die weltweit eindeutige ID des Arbeitsbereichs/Teams, dem dieser Bericht zugeordnet ist. |
Beispiel für Anfrage und Antwort 2
Anfrage:
GET https://dev.iclportal.com/api/services/app/reports/getofinspection?inspectionId=98e678a5-e771-46dd-b933-8a3ee9059684 HTTP/1.1
Host: dev.iclportal.com
Connection: keep-alive
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Authorization: Bearer <long token>
Antwort:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 204
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 25 Jan 2016 11:23:53 GMT
{
"results":[
{
"id":"c87be9ab-1d35-4c6a-8444-2aed3eb9a717",
"isDraft":false,
"reportState":3,
"fileName":"TheActualFilename.pdf",
"mimeType":"application/pdf",
"recipients":"",
"error":null,
"created":"2016-03-15T15:10:08.257Z",
"workAreaId":"51cd73f7-d176-4833-9bd5-903eb9d8c0d3"
}
],
"__count":1
}
3. Herunterladen von Berichten
Um einen generierten Bericht (reportstate=3) herunterzuladen, können Sie diese Url verwenden
Url: /get
HTTP-Methode: GET
Beispiel:
GET https://dev.iclportal.com/api/reports/get/<reportId> HTTP/1.1
| Name | Typ | Erforderlich? | Beschreibung |
|---|---|---|---|
| reportId | string | Erforderlich | Die eindeutige Identität des Berichts |
Der Server antwortet mit einem 200 OK, das die eigentliche Berichtsdatei im Antwortstrom enthält.
Sie benötigen die Berechtigung Reports.Download (global oder für das Team der Inspektion), außer Sie haben die Inspektion selbst erstellt.
| Statuscode | Bedeutung |
|---|---|
| 200 OK | Die Antwort enthält die Berichtsdatei |
| 403 Forbidden | Sie dürfen diesen Bericht nicht herunterladen |
| 404 Not Found | Es gibt keinen Bericht mit dieser ID oder seine Datei wurde nicht gefunden |
| 500 Internal Server Error | Der Bericht wurde (noch) nicht generiert, d.h. sein reportState ist nicht 3 |
Beispiel für Anfrage und Antwort 3
Anfrage:
GET https://dev.iclportal.com/api/reports/get/c87be9ab-1d35-4c6a-8444-2aed3eb9a717 HTTP/1.1
Host: dev.iclportal.com
Connection: keep-alive
Authorization: Bearer <long token>
Antwort:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/pdf
Content-Encoding: gzip
Expires: -1
Server: Microsoft-IIS/10.0
Set-Cookie: fileDownload=true; path=/
Content-Disposition: attachment; filename=TheActualFilename.pdf
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 01 Jun 2016 10:13:00 GMT
Content-Length: 83756
%PDF-1.5
4 0 obj
<</Type /Page/Parent 3 0 R/Contents 5 0 R/MediaBox [0 0 595.45001221 841.70001221]/Resources<</Font<</FAAAAH 7 0 R/FAAABA 10 0 R/FAAABD 13 0 R/FAAABG 16 0 R/FAAABJ 19 0 R/FAAACF 25 0 R>>/XObject<</X1 28 0 R>>>>/Group <</Type/Group/S/Transparency/CS/DeviceRGB>>/Annots[23 0 R 27 0 R ]>>
endobj
5 0 obj
<</Length 29 0 R/Filter /FlateDecode>>stream
x Y r M K N2 oԐR EY3. U I EOjf 6 _ _ y S~ = H * #\ . n 8 M ~x-
......
4. Abrufen geänderter Berichte
Diese API bietet Ihnen eine Möglichkeit, alle Berichte abzurufen, die sich seit dem letzten Aufruf der API geändert haben.
Dies wird mit Hilfe eines changeToken realisiert, den Sie in einem externen System speichern müssen.
Ein ausführlicheres Beispiel finden Sie in der Anleitung zu inkrementellen Änderungen.
Sie benötigen die Berechtigung Reports.View, um diesen Endpunkt zu verwenden. Lassen Sie beim ersten Aufruf den Parameter changeToken weg oder übergeben Sie 0.
GET https://dev.iclportal.com/api/services/custom/externalReports/GetChanges HTTP/1.1
Accept: application/json
Authorization: Bearer HwBUGEn1p9S5BJi6iM.....
Die Antwort liefert uns die Berichte (wie erwartet), enthält aber einen nextChangeToken und einen nextLink, womit wir die nächsten 500 geänderten Berichte abrufen können.
Jeder Bericht enthält die unter Abfrage von Berichten beschriebenen Felder und zusätzlich:
| Name | Typ | Beschreibung |
|---|---|---|
| isDeleted | boolean | Gibt an, ob der Bericht gelöscht wurde. |
| deletionTime | date | Der Zeitpunkt, an dem der Bericht gelöscht wurde. |
Anders als bei der Abfrage von Berichten liefert dieser Endpunkt nicht den fileName und mimeType eines Berichts; beide sind immer null.
{
"result": {
"results": [
{
"id": "4b2c2e24-52b6-4f3f-8efa-3fd7b15c3e0c",
"reportState": 3,
"error": null,
"isDraft": false,
"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",
"workbookDefinitionId": "89ec0d17-3131-4bea-bed0-5ac2d72a8ba9",
"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, // this also gives you deleted reports
"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",
"workbookDefinitionId": "89ec0d17-3131-4bea-bed0-5ac2d72a8ba9",
"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
}
Da dieser Endpunkt dazu dient, inkrementelle Änderungen zu erhalten, gibt er auch gelöschte Berichte zurück, sodass Sie diese entsprechend aus Ihrem System entfernen können.
Da es keine weiteren Änderungen mehr gibt, gibt das System einfach die letzte verfügbare Änderung zurück, was in der Regel genau der gleiche Änderungs-Token ist, den wir gerade in der Anfrage verwendet haben.
Sie können jedoch diesen Mechanismus nutzen, um direkt zur letzten Seite der geänderten Berichte zu gelangen, indem Sie den höchstmöglichen Änderungs-Token __________8 verwenden.
Dies ist praktisch, wenn Sie nur die Änderungen von jetzt an abrufen wollen und nicht alle historischen Änderungen durchgehen wollen.