Sikkepitje.nl

Sikkepitje.nl

this private cloud

De Magister SOAP interface

Oftewel de Magister Webservice en ook aangeduid met "Magister Webservices"...

5 feb 2013 - Paul Wiegmans -> mailto:p [period] wiegmans [snail] svok [period] nl, Technisch beheerder SVOK.

Je zoekt een oplossing om geautomatiseerd teams aan te maken voor al je leerlingen en docenten in de Office 365 omgeving van jouw school?

TeamSync is een koppeling tussen Magister en Microsoft School Data Sync ten behoeve van het geautomatiseerd aanmaken van klassenteams in Microsoft Office 365 voor docenten en leerlingen van een school, die willen samenwerken in een vakklas- of lesgroepverband. TeamSync is uitgebracht op GitHub onder GNU General Public License v3.0 .

Bezoek sikkepitje/TeamSync

Maakt jouw schooladministratie gebruik van Somtoday en ben je geinteresseerd in een koppeling tussen Somtoday en School Data Sync? Bezoek dan

DwayneSelsig/Somtoday2MicrosoftSchoolDataSync

Links

  • Aanbevolen leesvoer: "Handleiding Magister Webservices_1.0.pdf" te downloaden bij Schoolmaster

Uitleg

De Magister SOAP interface of Magister Webservice maakt het mogelijk om te communiceren met het schooladministratiesysteem via SOAP calls naar een URL. Je kunt hiermee queries doen, om informatie op te vragen of zelfs om gegevens te wijzigen. In praktische zin kun je queries doen via de webbrowser of een andere applicaties zoals bijvoorbeeld Excel of PowerShell.

De webservice is direct beschikbaar voor elke school. Vul je schoolnaam in de URL in https://{schoolnaam}.swp.nl:8800/doc om deze te bereiken voor jouw school. Een voorwaarde is wel dat het ip-adres van je internetverbinding toegevoegd moet zijn in de whitelist van Schoolmaster, anders kan er geen verbinding worden gemaakt met de webservice. Neem contact op met de Schoolmaster-helpdesk hiervoor.

De API documentatie is direct beschikbaar via een webinterface. Ga naar https://bonhoeffer.swp.nl:8800/doc, test de functies.

Een voorbeeld van een query vanuit de webbrowser: https://bonhoeffer.swp.nl:8800/doc?Function=GetData&Library=Data&SessionToken=soapuser%3BGeheim&Layout=BasisAD&Parameters=&Type=TAB

De hierna gebruikte gebruikers en lijsten zijn in Magister gedefinieerd in Beheer->Webservices->lijsten en gebruikers.

Toegang

Toegang wordt geregeld door de logincredentials te geven.

In de URL kan de GET-parameter "SessionToken" gevolgd worden door een sessiontoken zoals

 SessionToken=F4CA4D3A-9278-4968-9220-BA87A872C50C 

maar het kan ook een naam en wachtwoord bevatten zoals

 SessionToken=soapuser%3BGeheim

De %3B is ; dus het mag ook zo:

 SessionToken=soapuser;Geheim

Vanuit de documentatiewebsite (hier) kun je eerst de functie login testen en een geldige gebruikersnaam en wachtwoord geven. De functie retourneert een sessiontoken terug. Je kunt deze sessiontoken bij volgende aanroepen gebruiken van bijv de GetData functie.

De functie Login geeft een sessiontoken terug.

Result	True
ResultMessage	
SessionToken	0D595E0A-27FD-4826-A5F0-1903C406A38F

Maak lijst

In Beheer->Webservices->lijsten: Basis bevat kolommen:

  • stamnr
  • roepnaam
  • tussenv
  • achternaam
  • post.nr
  • post.nr.tv
  • post.postcode
  • post.plaats
  • klas
  • lesperiode

Via Excel webquery krijg ik 12000 leerlingen. Dit is teveel. Nu gaat het erom om de actieve leerlingen te filteren. Dat gebeurt ergens met de informatie uit Aanmeldingen. Zie kolomkiezer. aanmelding.aanmelding.lesperiode.algemeen.lesperiode = "0910"

Ik probeer in leerling->overzicht met de kolomkiezer de situatie te recreeren waarbij ik alleen de aktieve leerlingen krijg. Ik moet op een of andere manier via de kolomkiezer zelf de juiste velden en het juiste filter maken, die normaal gescproken in de werkbalk van Magister staat "actieve leerlingen". Maar zodra ik in de werkbalk "alle leerlingen" kies, in de kolomkiezer het veld lesperiode (aanmelding.aanmelding.lesperiode.algemeen.lesperiode) toevoeg, krijg ik een aantal foutmeldingen : 'The multi-part identifier "sis_blpe.lerperiode" could not be found.' 'The multi-part identifier "sis_bgrp.groep" could not be found.'

De oplossing: in Leerling->Overzicht, in de werkbalk kies "Alle aanmeldingen". Vanaf hier kunnen we in de kolomkiezer dezellfde situatie creeren als in Medius webservice. Standaard is het aantal leerlingen 12840. In kolomkiezer kies alle gewenste kolommen plus: aanmelding.aanmelding.lesperiode.algemeen.lesperiode.

Filter:

  • lesperiode is gelijk aan "0910"
  • klas niet als "XX%"

Aantal leerling is nu 1521. Het aantal werkelijke aktieve leerlingen is 1480. Het verschil? Peildatum ! Er wordt gekeken naar

DeciBel

Bekijk de query in DeciBel (log in als supervisor, klik linksbovenin->onderhoud->decibel). Ga naar Systeem -> ddlijsten. Dit zijn de lijsten voor WebService. Klik op Bewerken, selecteer het record BasisAD en dubbelklik op het veld Ssql om de query te zien. De query is als volgt:

select distinct
  sis_leer.roepnaam,
  sis_leer.achternaam,
  sis_leer.tussenvoeg,
  sis_leer.stamnr,
  sis_leer.p_pcode,
  sis_leer.p_plaats,
  sis_blpe.lesperiode as sis_blpe__lesperiode,
  sis_bgrp.groep as sis_bgrp__groep, sis_leer.idLeer as idLeer, sis_aanm.idAanm as sis_aanm__idAanm, sis_blpe.idBlpe as sis_blpe__idBlpe, sis_bgrp.idBgrp as sis_bgrp__idBgrp
from sis_leer sis_leer
  INNER JOIN sis_aanm sis_aanm on sis_leer.stamnr=sis_aanm.stamnr
  LEFT JOIN sis_blpe sis_blpe on sis_aanm.lesperiode=sis_blpe.lesperiode
  LEFT JOIN sis_bgrp sis_bgrp on sis_aanm.idBgrp=sis_bgrp.idBgrp
 WHERE (sis_aanm.dBegin <= '2010-01-28') and (sis_aanm.dEinde >= '2010-01-28') and
 ((sis_aanm.dVertrek >= '2010-01-28') or ( sis_aanm.dVertrek is null))
 and (sis_blpe.lesperiode = '0910')

Peildatum is iets wat vanuit de applicatie moet worden gegenereerd en doorgegeven aan Medius. Hoe ? Geen idee.

WebQuery via Excel.

Maak een tekstbestand en sla het op als magisterwebquery.iqy met dit:

WEB
1
https://bonhoeffer.swp.nl:8800/doc?Function=GetData&Library=Data&SessionToken=soapuser%3BGeheim&Layout=BasisAD&Parameters=&Type=TAB
Selection=EntirePage
Formatting=All
PreFormattedTextToColumns=True
ConsecutiveDelimitersAsOne=True
SingleBlockTextImport=False

of in het algemene definitie:

WEB
1
https://bonhoeffer.swp.nl:8800/doc?Function=GetData&Library=Data&SessionToken={gebruikersnaams}%3B{wachtwoord}&Layout={lijstnaam}&Parameters=&Type=TAB
Selection=EntirePage
Formatting=All
PreFormattedTextToColumns=True
ConsecutiveDelimitersAsOne=True
SingleBlockTextImport=False

Vul nu zelf de juiste gegevens in voor:

  • {gebruikersnaam}
  • {wachtwoord}
  • {lijstnaam}

De lijsten die je hier kunt kiezen zijn de lijsten die zijn gedefinieerd in Magisterschoolwerkplek (via Remote Desktop) in Beheer --> Webservices --> Lijsten. De gebruikersnaam die je hier invult is gedefinieerd in Beheer --> Webservices --> Gebruikers.

Waar staat Type=TAB kun je hier TAB vervangen door een van de volgende parameters bij de GetData-functie:

  • HTML - uitvoer in een nette HTML tabel
  • XML - uitvoer in XML
  • CSV - uitvoer in CSV, direct in te lezen in Excel
  • TAB - uitvoer in tabgescheiden waarden.

Zie https://bonhoeffer.swp.nl:8800/doc voor de beschikbare functies en om zelf functies te testen.

Een Webservice-gebruiker is aangemaakt: soapuser, wachtwoord is Geheim . Er zijn twee lijsten: Basis en BasisAD .

Webquery via PowerShell !!!!

Hoe ?

Een basale webquery kan in PowerShell worden uitgevoerd als volgt.

$url = "https://bonhoeffer.swp.nl:8800/doc?Function=GetData&Library=Data&SessionToken=soapuser%3BGeheim&Layout=BasisAD&Parameters=&Type=CSV"
$request = [System.Net.WebRequest]::Create($url)
$response = $request.GetResponse()
$requestStream = $response.GetResponseStream()
$readStream = new-object System.IO.StreamReader $requestStream
$aantal = 0
do {
	$line = $readStream.ReadLine()
	echo $line 
	$aantal += 1
} until ($readStream.EndOfStream)
Echo "Aantal gelezen regels is: $aantal"
$readStream.Close()
$response.Close()

Dit voorbeeld retourneert veel dubbele records. Het geeft namelijk een record per leerling per leerjaar. In een gemiddelde schoolloopbaan zit een leerling 4 tot 6 jaar op school. Er worden dus 4 to 6 records voor elke unieke leerling gegeven. Hier moet een selectie gemaakt worden om alleen de aktieve leerlingen te geven.

(tussendoor tip: combineer CSV's)

Kennis uit PDF "Magister Webservices"

Ga naar Beheer → Webservices

Gebruiker aanmaken

Beheer → Webservices → Gebruikers

Definieer een lijst

Beheer → Webservices → Lijsten

Een lijst aanmaken doe je met Kolomkiezer, zoals lijsten in Leerlingen --> Lijsten.

Daarna kun je in Decibel de query aanpassen in de tabel ddlijsten.

Klik op linksboven op Magister-icoontje, kies Decibel en voer het Decibel-wachtwoord in. Ga naar menu Scherm en klik Toon tabellen aan. Hiermee worden de kale tabellen zichtbaar in een lijst. Zoek en klik de tabel ddlijsten. Rechts verschijnt de inhoud van tabel "ddlijsten". In het record van de gewenste lijst dubbelklik op veld Ssql om de query te zien.

Lijst ophalen met GetData

Een call naar GetData via de SOAP interface doe je door in een webbrowser te tikken.

https://[MediusHost]:[MediusPort]/ 
?Library=Data 
&Function=GetData 
&SessionToken=[Gebruiker];[Wachtwoord] 
&Layout=[Naam van de Lijst] 
&Parameters=(optioneel, bijvoorbeeld stamnr%3D194103816)

Let op %3D betekent '='. Dus bijvoorbeeld

Die Layout=BasisAD&Parameters=stamnr%3D194103816 verbindt hier in de query aan "stamnr = #stamnr#" . Sleutelvelden in query ongeven door '#' laten zich vullen door de parameters gegeven door de overeenkomstige naam in de queryURL.

Real world queries

De query voor WISMASLEERLING is

select distinct
  sis_leer.roepnaam as mas_voornaam,
  sis_leer.tussenvoeg as mas_tussenvoegsel,
  sis_leer.achternaam as mas_achternaam,
  sis_leer.email as mas_email,
  sis_leer.stamnr as mas_leerlingnummer,
  sis_gebr.login_naam as magister_loginname,
  sis_leer.naam_vol as mas_volledige_naam,
  sis_bgrp.groep as mas_klas,
  sis_blok.c_lokatie as mas_lokatie,
  sis_pers0.doc_code as mas_mentor_persoonlijk, -- persoonlijke mentor
  sis_pers1.doc_code as mas_mentor_klas,        -- klassenmentor
  sis_pers2.doc_code as mas_mentor_assistent,   -- mentor assistent
sis_leer.idLeer as mas_leerlingId,
sis_pers0.idPers as mas_mentor_persoonlijk_persId,
sis_pers1.idPers as mas_mentor_klas_persId,
sis_pers2.idPers as mas_mentor_assistent_persID,
sis_leer.p_straat as mas_leerling_straat,
sis_leer.p_huisnr as mas_leerling_huisnr,
sis_leer.p_huisnrtv as mas_leerling_huisnrtv,
sis_leer.p_pcode as mas_leerling_postcode,
sis_leer.p_plaats as mas_leerling_plaats
from sis_leer sis_leer
  INNER JOIN sis_aanm sis_aanm on sis_leer.stamnr=sis_aanm.stamnr
  LEFT JOIN sis_bgrp sis_bgrp on sis_aanm.idBgrp=sis_bgrp.idBgrp
  LEFT JOIN sis_blok sis_blok on sis_bgrp.c_lokatie=sis_blok.c_lokatie
  LEFT JOIN sis_pers sis_pers0 on sis_aanm.idPers_mentor1=sis_pers0.idPers
  LEFT JOIN sis_pers sis_pers1 on sis_bgrp.idPers_mentor1=sis_pers1.idPers
  LEFT JOIN sis_pers sis_pers2 on sis_bgrp.idPers_mentor2=sis_pers2.idPers
  LEFT JOIN sis_gebr sis_gebr on sis_leer.idLeer=sis_gebr.idLeer
WHERE
sis_aanm.dvertrek is null and
sis_aanm.lesperiode = #leerjaar#
and getdate() between dbegin and deinde

De webqueryURL is dit

Basis

Webquery voor lijst "Basis" met parameter "leerjaar=1112"

Select DISTINCT sis_leer.tussenvoeg,
sis_leer.achternaam,
sis_leer.stamnr,
sis_leer.roepnaam,
sis_leer.telefoon1,
sis_leer.woonplaats,
sis_leer.idLeer,
sis_aanm.idStud as sis_aanm__idStud,
sis_aanm.idAanm as sis_aanm__idAanm,
sis_bgrp.groep as sis_bgrp__groep,
sis_leer.idLeer as idLeer,
sis_bgrp.idBgrp as sis_bgrp__idBgrp
From sis_leer sis_leer inner join sis_aanm on sis_leer.stamnr = sis_aanm.stamnr
left join sis_bgrp sis_bgrp on sis_aanm.idBgrp = sis_bgrp.idBgrp
Where
sis_aanm.dvertrek is null and
sis_aanm.lesperiode = #leerjaar#
and getdate() between dbegin and deinde

WISMASDOCENTEN

De query is

SELECT
  sis_pers.doc_code as mas_code,
  sis_gebr.login_naam as magister_loginname,
  sis_pers.voorlett as mas_voornaam,
  sis_pers.achternaam as mas_achternaam,
  sis_pers.naam_vol as mas_volledige_naam,
  sis_pers.doc_code as mas_docent_code,
  sis_pers.tussenvoeg as mas_tussenvoegsel,
  sis_pers.e_mailwerk as mas_email_werk,
  sis_pers.idPers as mas_persoon_id,
  sis_pers.c_hfd_lok as mas_locatie
FROM sis_pers sis_pers
LEFT JOIN sis_gebr sis_gebr ON sis_pers.idPers=sis_gebr.idPers
WHERE sis_pers.dVertrek is null 
OR sis_pers.dVertrek > GETDATE()

BasisTest

De query is

Select DISTINCT sis_leer.tussenvoeg,
sis_leer.achternaam,
sis_leer.stamnr,
sis_leer.roepnaam,
sis_leer.telefoon1,
sis_leer.woonplaats,
sis_leer.idLeer,
sis_aanm.idStud as sis_aanm__idStud,
sis_aanm.idAanm as sis_aanm__idAanm,
sis_bgrp.groep as sis_bgrp__groep,
sis_leer.idLeer as idLeer,
sis_bgrp.idBgrp as sis_bgrp__idBgrp
From sis_leer sis_leer inner join sis_aanm on sis_leer.stamnr = sis_aanm.stamnr
left join sis_bgrp sis_bgrp on sis_aanm.idBgrp = sis_bgrp.idBgrp
Where
sis_aanm.dvertrek is null and
sis_aanm.lesperiode = #leerjaar#

Nu juli 2012 aangepast tot

Select DISTINCT 
sis_leer.stamnr as leerlingnr,
sis_leer.roepnaam as voornaam,
sis_leer.tussenvoeg as tussenvoegsel,
sis_leer.achternaam as achternaam,
sis_leer.telefoon1 as telefoon,
CONCAT_WS(" ", sis_leer.p_STRAAT, CONCAT_WS(" ",sis_leer.p_HUISNR, sis_leer.p_HUISNRTV)) as straat,
sis_leer.p_pcode as postcode,
sis_leer.woonplaats,
sis_leer.idLeer,
sis_bgrp.groep as sis_bgrp__groep
From sis_leer sis_leer inner join sis_aanm on sis_leer.stamnr = sis_aanm.stamnr
left join sis_bgrp sis_bgrp on sis_aanm.idBgrp = sis_bgrp.idBgrp
Where
sis_aanm.dvertrek is null and
sis_aanm.lesperiode = #leerjaar#

Leerjaar wordt als parameter gegevens in de query-URL als volgt:

 https://bonhoeffer.swp.nl:8800/doc?Function=GetData&Library=Data&SessionToken=adfeeder%3BGeheim&Layout=Basistest&Parameters=leerjaar%3D1213&Type=HTML

De syntax voor parameters is

 parameters={parameters}

waarbij parameter bestaat uit :

 leerjaar%3D1213

Dit betekent eigenlijk leerjaar=1213 waarbij is-gelijk-teken is geURLencoded.

BasisAD

De query is

select distinct 
  sis_leer.stamnr as leerlingnr,
  sis_leer.roepnaam as voornaam,
  sis_leer.tussenvoeg as tussenvoegsel,
  sis_leer.achternaam as achternaam,
  sis_leer.telefoon1 as telefoon,
  CONCAT_WS(" ", sis_leer.p_STRAAT, CONCAT_WS(" ",sis_leer.p_HUISNR, sis_leer.p_HUISNRTV)) as straat,
  sis_leer.p_pcode as postcode,
  sis_leer.p_plaats as woonplaats,
  sis_bgrp.groep as klas
from sis_leer sis_leer 
  INNER JOIN sis_aanm sis_aanm on sis_leer.stamnr=sis_aanm.stamnr
  LEFT JOIN sis_bgrp sis_bgrp on sis_aanm.idBgrp=sis_bgrp.idBgrp
Where
sis_aanm.dvertrek is null and
sis_aanm.lesperiode = #leerjaar#

Encoding problemen

Huidige code:

$url = "https://bonhoeffer.swp.nl:8800/doc?Function=GetData&Library=Data&SessionToken=soapuser%3BGeheim&Layout=WISMASLEERLINGEN&Parameters=leerjaar%3D1112&Type=CSV"
$url = "https://bonhoeffer.swp.nl:8800/doc?Function=GetData&Library=Data&SessionToken=soapuser%3BGeheim&Layout=Basis&Parameters=leerjaar%3D1112&Type=CSV"
$request = [System.Net.WebRequest]::Create($url)
$response = $request.GetResponse()
$requestStream = $response.GetResponseStream()
$readStream = new-object System.IO.StreamReader $requestStream 
# sReader = New StreamReader(hResponse.GetResponseStream, Encoding.GetEncoding("ISO-8859-1"))
$lines = $readStream.ReadToEnd()
$readStream.Close()
$response.Close()

$lines | Out-File -FilePath "U:\soap2.csv" -Encoding ansi

# bepaal de velden : $fields = @($csv | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty name)

De encodign waarin ik data terugkrijg is ISO-8859-1 . PowerShell gaat ervan uit dat het data krijgt in UTF-8. Ik moet het zien om te zetten.

De beste oplossing hiervoor tot nu toe is om encoding UTF-7 te gebruiken. Het lost de meeste problemen op maar niet allemaal. Bijvoorbeeld Šromofský blijft niet intact. De code wordt dan zo:

	$request = [System.Net.WebRequest]::Create($Url)
	$response = $request.GetResponse()
	$requestStream = $response.GetResponseStream()
	$MagisterEncoding = [System.Text.Encoding]::UTF7  
	$readStream = new-object System.IO.StreamReader( $requestStream, $MagisterEncoding )

dubbele leerlingen in query

20130121

Het blijkt dat sommige leerlingen er dubbel in de resultaat van de webquery staan, wanneer deze leerling tussentijds van klas gewisseld is. Met het goede resultaat gegeven door de lijst "WISMASLEERLINGEN" en beetje proberen, blijkt dat de query voor lijst "Basis" wel het goede resultaat geeft , wanneer de query eindigt met voorwaarde:

and getdate() between dbegin and deinde

Deze toevoeging geeft nu 1536 resultaten in plaats van 1544 waar 8 leerling dubbel in voorkwamen.