INHALTSVERZEICHNIS
- Generell
- Verfügbare Endpoints
Generelles
- Für die Benutzung ist ein Planik-Benutzer zwingend nötig. Dieser muss lesenden Zugriff haben oder, für den Endpoint planungsverlauf, schreibenden Zugriff. D.h, im Fall 1 reicht die Rolle "Leser", sonst aber ist die Rolle "Planer" nötig
- Die Zeiten werden gemäss ISO 8601 Standard in lokaler (schweizer) Zeit inklusive Offset zu UTC angegeben.
- Beispiel: 2018-08-20 08:00:00 +0200. Der Dienst beginnt um 08:00 Uhr und hat 2 Stunden Offset zur UTC Zeit (Siehe Details hier: https://en.wikipedia.org/wiki/ISO_8601#Times)
- Maximal werden 1000 Records pro Anfrage geliefert. Ist Ihre Abfrage grösser (möglich bei der Abfragen der Dienste in einem grossen Team mit langer Zeitspanne), so verwenden Sie bitte DB-Paging. Hier ein Beispiel mit einer Pagesize von 10. Beispiel:
'https://api.planik.ch/api/v1/dienste?filter[team_id]=1152&filter[zwischen]=2018-08-01,2018-08-31&page[size]=10&page[number]=1' # Die ersten 10 Dienste: page[size]=10&page[number]=0 # Oder page[size]=10&page[number]=1 # die nächsten 10 Dienste page[size]=10&page[number]=2 # Die folgenden 10 Dienste page[size]=10&page[number]=3
- Die Daten werden als JSON Files unformatiert übertragen.Für eine für den Menschen schöne Darstellung der JSON Dokumente benutzen Sie zum Beispiel http://jsonprettyprint.com
Verfügbare Endpoints
login (POST)
- Jeder Planik-Benutzer welcher die entsprechenden Rechte hat (Lesender Zugriff auf Dienste und Mitarbeiter) kann grundsätzlich die API aufrufen.
- Wir verwenden eine tokenbasierte Authentifikation.
- Die Tokens sind maximal 24 Stunden gültig, danach müssen neue angefordert werden.
Abfrage mit curl:
curl -i \ -H 'Content-Type: application/json' \ -d '{"benutzer": {"email": "test@planik.ch", "password": "xxx"}}' \ https://api.planik.ch/api/v1/login
Details:
Login mit Email und Passwort in einem Json Objekt als POST-Request
{ "benutzer": { "email": "test@planik.ch", "password": "xxx" } }
Zurück kommen drei verschiedene Headers, welch man für die späteren Aufrufe verwenden muss:
- access-token (Beispiel: f2FLH8Xpo1ZQnt5OOdCP4g)
- client (pDumX4XC_34BS_2fN0_5jQ)
- uid (Emailadresse)
Der Body der Antwort kann ignoriert werden. Er sieht zum Beispiel so aus:
{ "data": { "email": "alexander.schuppisser@optor.ch", "vorname":"<Vorname>", "nachname":"<Nachname>", "id":123, "uid":"alexander.schuppisser@optor.ch", "is_internal_super_user":true, "wuenscht_email_wenn_plan_berechnet":true, "provider":"email", "locale_id":1, "dashboard_favorit_organisation_id":null, "dashboard_favorit_team_id":null, "type":"benutzer" } }
Klappt das Einloggen nicht, so wird folgende Meldung im Body der Antwort zurückgegeben:
{ "success": false, "errors": ["Ungültige Anmeldeinfomration. Bitte versuchen Sie es erneut."] }
mitarbeiter (GET)
Abfrage mit curl:
# -i include the headers # -g switches off the "URL globbing parser". Für [] in der URL curl -i -g \ -H 'Accept: application/json' \ -H 'access-token:NOMgqk2sS-850Dk5qzUlZQ' \ -H 'uid:christian.muehlethaler@planik.ch' \ -H 'client:4lKfU3CpTBuiTcvr-7XbuQ' \ 'https://api.planik.ch/api/v1/mitarbeiter?filter[team_id]=959&filter[angestellt_zwischen]=2018-08-01,2018-08-31'
Filter:
Default Filter: Keine. Es werden alle Mitarbeiter des Teams zurückgeliefert, auch solche die schon ausgetreten sind. Zwingende Filter: filter[team_id] Optionale Filter: filter[angestellt_zwischen] Werte: Zwei Daten, kommasepariert. Interpretation: Alle Mitarbeiter welche zwischen diesen Daten irgendwann angestellt sind filter[id] Werte: Kommaseparierte Liste von Mitarbeiter-IDs filter[kuerzel] Werte: Kommaseparierte Liste von Mitarbeiterkuerzel filter[personalnummer] Werte: Kommaseparierte Liste von Mitarbeiterpersonalnummer filter[schlagwort] Werte: Kommaseparierte Liste von Mitarbeiterschlagworte
fields:
fields[mitarbeiter]: Kommaseparierte Felder der Mitarbeiter welche interessieren fields[anstellung]: fields[arbeitsvertrag]:
include:
Die verknüpften Ressourcen, welche man gerne in der gleichen Abfrage erhalten möchte. Möglich sind: 'anstellungen' und 'anstellungen.arbeitsvertrag'
filter[anstellungen][aktiv_zwischen]: Werte: Zwei Daten, kommasepariert. Interpretation: Alle Dienste welche zwischen diesen Daten beginnen
arbeitsvertraege (GET)
Liefert alle Typen von Arbeitsverträgen.
Abfrage mit curl:
# -i include the headers # -g switches off the "URL globbing parser". Für [] in der URL curl -i -g \ -H 'Accept: application/json' \ -H 'access-token:NOMgqk2sS-850Dk5qzUlZQ' \ -H 'uid:christian.muehlethaler@planik.ch' \ -H 'client:4lKfU3CpTBuiTcvr-7XbuQ' \ 'https://api.planik.ch/api/v1/arbeitsvertraege?filter[team_id]=959'
Filter:
Default Filter: Keine. Zwingende Filter: filter[team_id] Optionale Filter: keine
fields:
fields[arbeitsvertrag]: Kommaseparierte Felder der Mitarbeiter welche interessieren
include:
keine
plaene (GET)
Liefert alle veröffentlichte Pläne eines Teams, aufsteigend sortiert. Es wird datum_von und datum_bis des Plans geliefert.
Abfrage mit curl:
# -i include the headers # -g switches off the "URL globbing parser". Für [] in der URL curl -i -g \ -H 'Accept: application/json' \ -H 'access-token:NOMgqk2sS-850Dk5qzUlZQ' \ -H 'uid:christian.muehlethaler@planik.ch' \ -H 'client:4lKfU3CpTBuiTcvr-7XbuQ' \ 'https://api.planik.ch/api/v1/plaene?filter[team_id]=959&filter[zwischen]=2020-01-01,2020-08-31'
Filter:
Default Filter: Keine. Zwingende Filter: filter[team_id] Optionale Filter: filter[zwischen]=2020-01-01,2020-08-31: Alle Pläne welche zwischen den beiden Datenpunkte beginnen
fields:
fields[plan]: datum_von, datum_bis
include:
keine
dienstvorlagen (GET)
Liefert alle Dienstvorlagen eines Teams.
Abfrage mit curl
# -i include the headers # -g switches off the "URL globbing parser". Für [] in der URL curl -i -g \ -H 'Accept: application/json' \ -H 'access-token:NOMgqk2sS-850Dk5qzUlZQ' \ -H 'uid:christian.muehlethaler@planik.ch' \ -H 'client:4lKfU3CpTBuiTcvr-7XbuQ' \ 'https://api.planik.ch/api/v1/dienstvorlagen?filter[team_id]=959'
Beispielsantwort:
{ "data": [ { "id": "64572", "type": "dienstvorlage", "attributes": { "kuerzel": "SPEZ", "schluessel_dienst_typ": "DIENST", "zeit_von": "2000-01-01T15:00:00+01:00", "zeit_bis": "2000-01-01T20:00:00+01:00", "legende": "Spezialdienst Plaza", "notiz": "", "pause_zeit_von": null, "pause_zeit_bis": null, "schlagworte": [] } }, ...
Filter:
Default Filter: filter[aktivitaetstyp] Kommaseparierte Liste der Werte 'aktiv' und 'inaktiv'. Defaultwert ist 'aktiv' Zwingende Filter: filter[team_id] Optionale Filter: filter[kuerzel] filter[schluessel_dienst_typ] Kommaseparierte Liste von Schlüssel der Diensttypen DIENST, FERIEN, ABWESENHEIT filter[schlagwort] Kommaseparierte Liste von Schlagworte
fields:
fields[dienstvorlage]:
include:
keine
dienste (GET)
Liefert alle veröffentlichten Dienste eines Teams innerhalb eines bestimmten Zeitfensters.
Abfrage mit curl:
# -i include the headers # -g switches off the "URL globbing parser". Für [] in der URL curl -i -g \ -H 'Accept: application/json' \ -H 'access-token:NOMgqk2sS-850Dk5qzUlZQ' \ -H 'uid:christian.muehlethaler@planik.ch' \ -H 'client:4lKfU3CpTBuiTcvr-7XbuQ' \ 'https://api.planik.ch/api/v1/dienste?filter[team_id]=959&filter[zwischen]=2018-04-01,2018-04-30&include=mitarbeiter'
Beispielsantwort (ohne include):
{ "data": [ { "id": "40573157", "type": "dienst", "attributes": { "datum_zeit_von": "2022-04-01T00:00:00+02:00", "datum_zeit_bis": "2022-04-01T23:59:00+02:00", "pause_datum_zeit_von": "2022-04-01T12:00:00+02:00", "pause_datum_zeit_bis": "2022-04-01T12:30:00+02:00", "mitarbeiter_id": 60467, "kuerzel": "Fe", "schluessel_dienst_typ": "FERIEN", "arbeitszeit_sekunden": 0, "schlagworte": [], "notiz": null, "aenderung_id": "91904" }, "relationships": { "mitarbeiter": { "meta": { "included": false } } } }, ... ], "meta": {} }
Filter:
Default Filter: filter[nur_zugewiesene][eq]=true filter[zwischen]: Dienste zwischen heute und 30 Tage in der Zukunft Zwingende Filter: filter[team_id] Optionale Filter: filter[zwischen]: Werte: Zwei Daten, kommasepariert. Interpretation: Alle Dienste welche zwischen diesen Daten beginnen filter[schluessel_dienst_typ]: Werte: Kommaseparierte Liste der Diensttypen DIENST, FERIEN, ABWESENHEIT. Interpretation: OR-Verknüpfung filter[schlagwort]: Werte: Kommaseparierte Liste von Schlagworte auf den Dienstvorlagen. Interpretation: OR-Verknüpfung filter[mitarbeiter_kuerzel]: Werte: Kommaseparierte Liste von Mitarbeiterkürzel Interpretation: Nur Dienste dieser Mitarbeiter filter[mitarbeiter_personalnummer]: Werte: Kommaseparierte Liste von Personalnummern Interpretation: Nur Dienste dieser Mitarbeiter filter[mitarbeiter_schlagwort]: Werte: Kommaseparierte Liste von Schlagworte auf den Mitarbeitern Interpretation: Nur Dienste dieser Mitarbeiter
fields:
fields[dienst]: Kommaseparierte Felder der Dienstressource welche interessieren (inklusive der Notizen der Dienste als String) fields[mitarbeiter]: Kommaseparierte Felder der Mitarbeiter welche interessieren. (In dem Fall muss die Mitarbeiter-Ressource inkludiert werden)
include:
Möglich sind: 'mitarbeiter', 'mitarbeiter.anstellungen' und 'mitarbeiter.anstellungen.arbeitsvertrag'. Beispiel: include=mitarbeiter,mitarbeiter.anstellungen,mitarbeiter.anstellungen.arbeitsvertrag Werden diese inkludiert, so kann man noch weitere Filter setzen. Bsp: Nur Anstellungen welche in der gewünschten Zeitperiode relevant sind: filter[mitarbeiter.anstellung][aktiv_zwischen]: Werte: Zwei Daten, kommasepariert. Interpretation: Alle Dienste welche zwischen diesen Daten beginnen
Sortierung:
Default: Nach 'datum_zeit_von' aufsteigend Spezifiziert, Beispiele: &sort=mitarbeiter_id,datum_zeit_von &sort=-datum_zeit_von
Statistiken:
stats[total]=count: Die Anzahl Dienste in der Abfrage (Paging wird ignoriert)
api/v1/dienste?filter[team_id]=1152&filter[zwischen]=2018-08-01,2018-08-31&stats[total]=count Die Anzahl wird im "statistic" Block der Antwort geliefert. (Nach allen Diensten). Antwortbeispiel: "meta": { "stats": { "total": { "count": 31 } } }
Zusätzliche Information:
Beispiel von mehreren Abfragen im Life-cycle eines Plans
Für Jede Planänderung (Dienst erstellen, Dienst ändern (auch Dienst verschieben), Dienst löschen, Plan veröffentlichen) wird eine neue ÄnderungID generiert und der betroffenen Dienstversion zugeordnet. Hier schematisch ein Beispiel wie das in einem LifeCycle eines Plans aussieht.
# Curl-Abfrage eines Plans: Nur Kürzel und ÄnderungID der Dienste curl -i -g \ ... \ 'https://api.planik.ch/api/v1/dienste?filter[team_id]=673&filter[zwischen]=2018-10-01,2018-10-31&&fields[dienst]=kuerzel,aenderung_id'
#-> Im Planik GUI leerer Oktoberplan erstellt #-> NeuerDienst F1 erstellt: 3943 #-> Plan veröffentlicht: ÄnderungID 3944 #-> Resultat der Abfrage: {"kuerzel":"F1","aenderung_id":3943} # Auch ein neuer Dienst hat seine ÄnderungID
#-> Neuer Dienst F2 erstellt: ÄnderungID 3945 #-> Plan veröffentlicht: ÄnderungID 3946 #-> Resultat der Abfrage: {"kuerzel":"F1","aenderung_id":3943}, {"kuerzel":"F2","aenderung_id":3945}
#-> Neuer Dienst in anderer Zeitperiode (aber auf gleichem Team) erstellt: ÄnderungID 3947 #-> Neuer Dienst F3 erstellt: ÄnderungID 3948 #-> Plan veröffentlicht: ÄnderungID 3949 #-> Resultat der Abfrage: {"kuerzel":"F1","aenderung_id":3943} {"kuerzel":"F2","aenderung_id":3945} {"kuerzel":"F3","aenderung_id":3948}
#-> Dienst F2 gelöscht: ÄnderungID 3949 #-> Dienst F1 geändert: ÄnderungID 3950 #-> Plan veröffentlicht: ÄnderungID 3951 #-> Resultat der Abfrage: {"kuerzel":"F1","aenderung_id":3951} # Wurde geändert, darum neue ÄnderungID {"kuerzel":"F3","aenderung_id":3948} # Wurde nicht geändert, darum ursprüngliche ÄnderungID
planungsverlauf/[team_id] (PATCH)
Dieser Endpoint ist ein schreibender Endpoint. Es wir der Planungsverlauf manipuliert. Dienste werden gelöscht und neue Dienste werden hinzugefügt.
Die Informationen über die einzelnen Aktionen werden im payload (JSON File) beschrieben. Aktuell gibt es 3 verschiedene Aktionen mit denen die Dienste gelöscht und hinzugefügt werden können.
- Dienste löschen mit der Action "delete"
- Dienste hinzufügen mit den Action "add" und "add_sequence"
Abfrage mit curl:
- Die team_id wird in der URL mitgeliefert, im Beispiel 999
- Ein oder mehere Actions werden als Attribute im JSON File geliefert
curl -i \ --header "Content-Type: application/json" \ -H 'access-token:5bb7p1t5PMIIr9c2KeoU6Q' \ -H 'uid:christian.muehlethaler@planik.ch' \ -H 'client:aF8uyWRcdGNkwAKZcGy_0A' \ --request PATCH \ --data '{ "data": { "type": "planungsverlauf", "attributes": { "actions": [ { "action": "add", "type": "dienst", "attributes": { "datum": "2019-01-06" }, "relationships": { "dienstart": { "data": { "type": "dienstart", "filters": { "kuerzel": { "eq": "B" } } } }, "mitarbeiter": { "data": { "type": "mitarbeiter", "filters": { "kuerzel": { "eq": "SKO" } } } } } } ] } } }' \ https://api.planik.ch/api/v1/planungsverlauf/999
Action-Elemente:
Es gibt drei verschiedene Aktionstypen:
- delete: löscht alle spezifizierten Dienste
- add: Erstellt den spezifizierten Dienst für den spezifzierten Mitarbeiter
- add_sequence: erstellt die spezifizierten Dienste dem spezifizieren Mitarbeiter (es können auch mehrere Sein) in der spezifizierten Periodizität
Diese Actions werden nacheinander innerhalb der gleichen DB-Transaktion abgearbeitet. Schlägt also eine einzige Action fehl, so wird gar nichts auf die Datenbank geschrieben, auch nicht die vorhergegangenen erfolgreichen Aktionen.
Action 'delete'
Element | Name | Verwendung | Werte | Beispiel |
---|---|---|---|---|
filter | datum_zeit_von | zwingend | Array von zwei Daten | "datum_zeit_von": { "between": ["2020-03-01", "2020-03-31"]} |
filter | mitarbeiter_id | optional | Integer oder "null" (Alle Dienste welche keinem Mitarbeiter zugewiesen sind) | "mitarbeiter_id": { "eq": null} |
filter | mitarbeiter.kuerzel | optional | Einzelner oder Array von Mitarbeiterkürzel als Strings | "mitarbeiter.kuerzel": { "eq": ["SI", "MU"]} |
filter | mitarbeiter.personalnummer | optional | Einzelner oder Array von Personalnummer als Strings | "mitarbeiter.personalnummer": { "eq": ["2589", "33984"]} |
filter | dienstart.kuerzel | optional. Wenn nicht gesetzt: Alle Dienste unabhängig der Dienstvorlage | Einzelner oder Array von Dienstvorlagenkürzel als Strings | "dienstart.kuerzel": { "eq": ["Früh", "Mi"]} |
Beispiel:
{ "action": "delete", "type": "dienst", "filters": { "datum_zeit_von": { "between": [ "2020-03-01", "2020-03-31" ] }, "mitarbeiter.kuerzel": { "eq": "IZ"}, "dienstart.kuerzel": { "eq": "HVZ"} }
Action 'add':
Fügt einen einzelnen Dienst in den Planungsverlauf hinzu. Dieser Dienst kann von der Dienstvorlage abweichen, falls gewünscht. Entweder wird der Dienst direkt einem Mitarbeiter zugewiesen (relationship 'mitarbeiter') oder, falls diese fehlt, dem Planbedarf hinzugefügt.
Element | Name | Verwendung | Werte | Beispiel |
---|---|---|---|---|
Attribut | datum | zwingend (optional wenn 'datum_zeit_von' und 'datum_zeit_bis' gesetzt) | ISO String des Datums. Definiert das Startdatum des Dienstes | "datum": "2020-03-06" |
Attribut | datum_zeit_von | optional (zwingend wenn 'datum' nicht gesetzt) | ISO String eines Zeitstempels. Überschreibt "zeit_von" der Dienstvorlage | "datum_zeit_von": "2020-03-06 08:15:00 +0100" |
Attribut | datum_zeit_bis | optional (zwingend wenn 'datum' nicht gesetzt) | ISO String eines Zeitstempels. Überschreibt "zeit_bis" der Dienstvorlage | "datum_zeit_von": "2020-03-06 16:00:00 +0100" |
relationship | dienstart | zwingend | JSON Element welche die Dienstvorlage für den gewünschten definiert | "dienstart": { "data": { "type": "dienstart", "filters": { "kuerzel": { "eq": "B" } } } } |
relationship | mitarbeiter | optional. Wenn nicht gesetzt, so wird der Dienst im Dienstbedarf erstellt. | "mitarbeiter": { "data": { "type": "mitarbeiter", "filters": { "kuerzel": { "eq": "ZI" } } } } |
Beispiel:
{ "action": "add", "type": "dienst", "attributes": { "datum_zeit_von": "2020-03-06 08:15:00 +0100", "datum_zeit_bis": "2020-03-06 16:00:00 +0100" }, "relationships": { "dienstart": { "data": { "type": "dienstart", "filters": { "kuerzel": { "eq": "B" } } } }, "mitarbeiter": { "data": { "type": "mitarbeiter", "filters": { "kuerzel": { "eq": "ZI" } } } } } }
Action 'add_sequence':
Mit dieser Action können ganze Sequenzen von Dienste hinzugefügt werden. Zum Beispiel ist es möglich, jedem Mittwoch im Sommerhalbjahr den Mitarbeitern X, Y und Z einen Dienst "A" hinzuzufügen.
Im Gegensatz zur 'add' Action ist es jedoch nicht mögich, den Diensten von der Dienstvorlage abweichende Attributwerte mitzugeben.
Element | Name | Verwendung | Werte | Beispiel |
---|---|---|---|---|
Attribut | quantity | zwingend | Integer, zwischen 1 und 5 | |
Attribut | period | zwingend | String, entweder "daily" oder "weekly" | "period": "weekly", |
Attribut | start | zwingend | ISO String eines Datums | "start": "2020-03-06" |
Attribut | end | zwingend | ISO String eines Datums | "end": "2020-03-10" |
relationship | dienstart | zwingend | JSON Element welche die Dienstvorlage für den gewünschten definiert | "dienstart": { "data": { "type": "dienstart", "filters": { "kuerzel": { "eq": "B" } } } } |
relationship | mitarbeiter | optional. Wenn nicht gesetzt, so werden die Dienste im Dienstbedarf erstellt. Sonst wird jedem Mitarbeiter, die der Filter liefert, die Dienste erstellt | "mitarbeiter": { "data": { "type": "mitarbeiter", "filters": { "kuerzel": { "eq": "ZI" } } } } |
Beispiel:
{ "action": "add_sequence", "type": "dienst", "attributes": { "quantity": 1, "period": "daily", "start": "2019-01-01", "end": "2019-01-31" }, "relationships": { "dienstart": { "data": { "type": "dienstart", "filters": { "kuerzel": { "eq": ["B", "SU"] } } } }, "mitarbeiter": { "type": "mitarbeiter", "data": { "type": "mitarbeiter", "filters": { "kuerzel": { "eq": ["SKO"] } } } } } }