Skip to content

Commit

Permalink
Ouder/verzorger synchronisatie toegevoegd. Versienummer toegevoegd.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dwayne Selsig committed May 5, 2022
1 parent 3c02a7b commit e10c59d
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 133 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ Tip: Maak een scheduled task aan. Het synchroniseren van leerlingegevens is alle
## Configuratiestappen na installatie
Ga naar de installatie directory en bewerk Somtoday2MicrosoftSchoolDataSync.exe.config in een text editor.

### endpoint address
Sinds 13 februari 2021 is het adres voor iedereen: https://oop.somtoday.nl/services/umService

### BooleanFilterBylocation

Filter toepassen of alle vestigingen opvragen.
Expand Down Expand Up @@ -67,9 +64,12 @@ Maak voor elke vestiging een eigen map aan. Dit kan gebruikt worden als je meerd
* False: alle gegevens in bovenstaande OutputDirectory opslaan.
* True: maak voor elke vestiging een eigen directory aan. Dit worden subdirectories in de OutputDirectory.

Dit is noodzakelijk als je meer dan 500.000 rijen in één bestand hebt. https://docs.microsoft.com/en-us/schooldatasync/csv-files-for-school-data-sync#required-csv-files-for-school-data-sync

### EnableGuardianSync
* False: Informatie over ouders/verzorgers wordt niet gesynct.
* True: Er worden 2 extra CSV-bestanden aangemaakt met informatie over de ouders/verzorgers.

Let op! Leerlingen ouder dan 18 jaar kunnen ervoor kiezen dat ouders geen inzage hebben in hun schoolprestaties. Aangezien deze keuze niet wordt doorgegeven door Somtoday, moet de instelling voor de wekelijkse samenvatting per e-mail voor iedereen uitgeschakeld blijven. Standaard staat deze e-mail uit, zie deze link voor meer informatie:
https://docs.microsoft.com/en-us/MicrosoftTeams/expand-teams-across-your-org/assignments-in-teams#weekly-guardian-email-digest

## Volgende stappen

Expand Down
61 changes: 30 additions & 31 deletions Somtoday2MicrosoftSchoolDataSync/App.config
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="UmServiceSoapBinding" maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000">
<security mode="Transport"/>
</binding>
<binding name="UmServiceSoapBinding1"/>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://oop.somtoday.nl/services/umService" binding="basicHttpBinding" bindingConfiguration="UmServiceSoapBinding" contract="UmService.UmService" name="umService"/>
</client>
</system.serviceModel>
<appSettings>
<add key="BooleanFilterBylocation" value="True"/>
<add key="IncludedLocationCode" value="AB;CD;EF;GH"/> <!-- Gescheiden door Puntcomma ; -->
<add key="umServiceBrinNr" value="01AB"/>
<add key="umServiceUsername" value="Somtoday-username"/>
<add key="umServicePassword" value="Somtoday-password"/>
<add key="OutputDirectory" value="C:\SchoolDataSync\CSV"/>
<add key="SeperateOutputDirectoryForEachLocation" value="True"/>
<add key="OutputFormatUsernameTeacher" value="{user.medewerkerUsername}"/>
<!--<add key="OutputFormatFirstnameTeacher" value="{user.medewerkerVoorletters}" /> -->
<!--<add key="OutputFormatLastnameTeacher" value="{user.medewerkerAchternaam}" /> -->
<add key="OutputFormatUsernameStudent" value="{user.leerlingNummer}"/>
<!--<add key="OutputFormatFirstnameStudent" value="{user.leerlingRoepnaam}" /> -->
<!--<add key="OutputFormatLastnameStudent" value="{user.leerlingAchternaam}" /> -->
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="UmServiceSoapBinding" maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000">
<security mode="Transport"/>
</binding>
<binding name="UmServiceSoapBinding1"/>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://oop.somtoday.nl/services/umService" binding="basicHttpBinding" bindingConfiguration="UmServiceSoapBinding" contract="UmService.UmService" name="umService"/>
<!-- Prod: https://oop.somtoday.nl/services/umService -->
<!-- Test: https://oop.test.somtoday.nl/services/umService -->
</client>
</system.serviceModel>
<appSettings>
<add key="BooleanFilterBylocation" value="True"/>
<add key="IncludedLocationCode" value="AB;CD;EF;GH"/> <!-- Gescheiden door Puntcomma ; -->
<add key="umServiceBrinNr" value="01AB"/>
<add key="umServiceUsername" value="Somtoday-username"/>
<add key="umServicePassword" value="Somtoday-password"/>
<add key="OutputDirectory" value="C:\SchoolDataSync\CSV"/>
<add key="SeperateOutputDirectoryForEachLocation" value="True"/>
<add key="OutputFormatUsernameTeacher" value="medewerkerUsername"/>
<add key="OutputFormatUsernameStudent" value="leerlingNummer"/>
<add key="EnableGuardianSync" value="False"/>
</appSettings>
</configuration>
44 changes: 26 additions & 18 deletions Somtoday2MicrosoftSchoolDataSync/Helpers/EventLogHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void WriteLog(string Message, EventLogEntryType eventType = EventLogEntry
}
catch (Exception ex)
{

}
}

Expand Down Expand Up @@ -91,27 +91,35 @@ internal void CreateLog()
bool read = task.Wait(10000);
if (read)
{
var proc = new ProcessStartInfo
{
UseShellExecute = true,
FileName = @"powershell.exe",
Arguments = "-command New-EventLog -Source \"" + appLog.Source + "\" -LogName \"" + appLog.Log + "\"",
Verb = "runas"
};

try
{
Process powerShellCreateEntry = Process.Start(proc);
powerShellCreateEntry.EnableRaisingEvents = true;
powerShellCreateEntry.Exited += powerShellCreateEntry_Exited;
Console.WriteLine("Eventlog wordt aangemaakt.");
System.Diagnostics.EventLog.CreateEventSource(source: appLog.Source, logName: appLog.Log);
}
catch (Exception ex)
catch (Exception normalCreate)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(String.Format("Eventlog aanmaken mislukt! ", ex.Message));
Console.ResetColor();
boolLogCreating = false;
//waarschijnlijk draait SDSsync niet als Admin.
var proc = new ProcessStartInfo
{
UseShellExecute = true,
FileName = @"powershell.exe",
Arguments = "-command New-EventLog -Source \"" + appLog.Source + "\" -LogName \"" + appLog.Log + "\"",
Verb = "runas"
};

try
{
Process powerShellCreateEntry = Process.Start(proc);
powerShellCreateEntry.EnableRaisingEvents = true;
powerShellCreateEntry.Exited += powerShellCreateEntry_Exited;
Console.WriteLine("Eventlog wordt aangemaakt.");
}
catch (Exception powerShellCreate)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(String.Format("Eventlog aanmaken mislukt! ", powerShellCreate.Message));
Console.ResetColor();
boolLogCreating = false;
}
}
int timeout = 0;
while (boolLogCreating)
Expand Down
18 changes: 17 additions & 1 deletion Somtoday2MicrosoftSchoolDataSync/Helpers/FileHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class FileHelper

internal bool WriteSDStoFiles(string path, SDScsv sdscsv)
{
EventLogHelper eh = new EventLogHelper();
EventLogHelper eh = Program.eh;
if (sdscsv.Schools.Count() > 0 &&
sdscsv.Sections.Count() > 0 &&
sdscsv.Teachers.Count() > 0 &&
Expand Down Expand Up @@ -71,6 +71,22 @@ internal bool WriteSDStoFiles(string path, SDScsv sdscsv)
csv.Configuration.RegisterClassMap<StudentEnrollmentCSVMap>();
csv.WriteRecords(sdscsv.StudentEnrollments); // where values implements IEnumerable
}
if (sdscsv.User.Count() > 0 && sdscsv.Guardianrelationship.Count() > 0)
{
using (TextWriter writer = new StreamWriter(path + @"user.csv"))
{
var csv = new CsvWriter(writer);
csv.Configuration.RegisterClassMap<GuardianCSVMap>();
csv.WriteRecords(sdscsv.User); // where values implements IEnumerable
}
using (TextWriter writer = new StreamWriter(path + @"guardianrelationship.csv"))
{
var csv = new CsvWriter(writer);
csv.Configuration.RegisterClassMap<GuardianRelationshipCSVMap>();
csv.WriteRecords(sdscsv.Guardianrelationship); // where values implements IEnumerable
}
}

if (sdscsv.Schools.Count == 1)
{
eh.WriteLog(String.Format("CSV-bestanden geschreven: {0}, {1} Lesgroepen, {2} Docenten, {3} Leerlingen, {4} Docentlesgroepen, {5} Leerlinglesgroepen, naar {6}",
Expand Down
80 changes: 73 additions & 7 deletions Somtoday2MicrosoftSchoolDataSync/Helpers/SDScsvHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ class SDScsvHelper
List<VestigingLesgroepModel> vestigingLesgroepen;
List<UserLesgroepModel> docentLesgroepen;
List<UserLesgroepModel> leerlingLesgroepen;
List<UserLesgroepModel> ouderLesgroepen;
SettingsHelper sh = new SettingsHelper();

public SDScsvHelper(List<VestigingLesgroepModel> vestigingLesgroepenModel, List<UserLesgroepModel> docentLesgroepenModel, List<UserLesgroepModel> leerlingLesgroepenModel)
public SDScsvHelper(List<VestigingLesgroepModel> vestigingLesgroepenModel, List<UserLesgroepModel> docentLesgroepenModel, List<UserLesgroepModel> leerlingLesgroepenModel, List<UserLesgroepModel> ouderLesgroepenModel)
{
vestigingLesgroepen = vestigingLesgroepenModel;
docentLesgroepen = docentLesgroepenModel;
leerlingLesgroepen = leerlingLesgroepenModel;
ouderLesgroepen = ouderLesgroepenModel;
}


Expand All @@ -38,13 +40,18 @@ internal SDScsv GetSDScsv()
List<TeacherRoster> TeacherRosters = GetTeacherRosters();
List<StudentEnrollment> StudentEnrollments = GetStudentEnrollments(Sections);

Tuple<List<Guardian>, List<GuardianRelationship>> ouderData = GetGuardianData();
List<Guardian> Guardians = ouderData.Item1;
List<GuardianRelationship> GuardianRelationships = ouderData.Item2;

_sdscsv.Schools = Schools;
_sdscsv.Sections = Sections;
_sdscsv.Teachers = Teachers;
_sdscsv.Students = Students;
_sdscsv.TeacherRosters = TeacherRosters;
_sdscsv.StudentEnrollments = StudentEnrollments;
_sdscsv.User = Guardians;
_sdscsv.Guardianrelationship = GuardianRelationships;
Console.WriteLine();

return _sdscsv;
Expand Down Expand Up @@ -154,8 +161,6 @@ private List<Teacher> GetTeachers()
SISid = employee.medewerkerNummer,
SISSchoolid = sISSchoolid,
Username = sh.ReplaceTeacherProperty(SettingsHelper.OutputFormatUsernameTeacher, employee),
//Firstname = sh.ReplaceTeacherProperty(SettingsHelper.OutputFormatFirstnameTeacher, employee),
//Lastname = sh.ReplaceTeacherProperty(SettingsHelper.OutputFormatLastnameTeacher, employee),
});
}
}
Expand Down Expand Up @@ -184,9 +189,6 @@ private List<Student> GetStudents()
SISid = student.leerlingNummer.ToString(),
SISSchoolid = userLesgroep.VestigingLesgroep.Vestiging.id.ToString(),
Username = sh.ReplaceStudentProperty(SettingsHelper.OutputFormatUsernameStudent, student),
//Firstname = sh.ReplaceStudentProperty(SettingsHelper.OutputFormatFirstnameStudent, student),
//Lastname = sh.ReplaceStudentProperty(SettingsHelper.OutputFormatLastnameStudent, student),

});
}
}
Expand Down Expand Up @@ -286,10 +288,74 @@ private List<StudentEnrollment> GetStudentEnrollments(List<Section> sections)
return _studentEnrollments;
}

private Tuple<List<Guardian>, List<GuardianRelationship>> GetGuardianData()
{
// https://docs.microsoft.com/en-us/schooldatasync/parent-contact-sync-file-format
Console.Write("Oudergegevens samenstellen");
int i = 0;

List<Guardian> ouders = new List<Guardian>();
List<GuardianRelationship> ouderRelaties = new List<GuardianRelationship>();
foreach (UserLesgroepModel ouderLesgroep in ouderLesgroepen)
{
List<UmService.webserviceUmObject> leerlingenVanDeVestiging = leerlingLesgroepen.Where(vl => vl.VestigingLesgroep == ouderLesgroep.VestigingLesgroep).Select(l => l.Users.Where(o => !string.IsNullOrEmpty(o.leerlingUsername) && o.leerlingActief.ToLower() == "actief" && !string.IsNullOrEmpty(o.leerlingUsername)).Distinct().ToList()).FirstOrDefault();
foreach (var ouderObject in ouderLesgroep.Users)
{
foreach (var leerlingData in ouderObject.verzorgerLeerlingRelaties.Split(':'))
{
i++;
if (i > 100)
{
Console.Write(".");
i = 0;
}
string[] ouderGegevens = leerlingData.Split(',');
/* De opbouw van de verzorgerLeerlingRelaties is verder als volgt:
[0]BurgerServiceNummer leerling, [1]Onderwijsnummmer leerling, [2]leerlingnummer, [3]relatie type, [4]Wettelijk, [5]Factuur, [6]Post, [7]extern debiteurnummer.
Als er geen BSN bekend is, gebruik je het onderwijsnummer (deze wordt dan door DUO verstrekt). Wettelijk, factuur en post zijn kenmerken in Somtoday. Een school kan deze vrij gebruiken. Indien aangevinkt geeft dit de waarde ja, anders een nee.
Indien factuur ja is, wordt er een extern debiteurnummer meegegeven.
Indien de verzorger meerdere kinderen als leerlingen heeft, worden deze achter elkaar getoond met een dubbele punt (:) als scheidingsteken.
*/
if (ouderGegevens[4].ToLower() == "ja") //Indien dit de wettelijke ouder/voogd is.
{
if (!string.IsNullOrEmpty(ouderObject.verzorgerEmail)) //Als de ouder een e-mailadres heeft
{
UmService.webserviceUmObject gevondenLeerling = leerlingenVanDeVestiging.Where(l => l.leerlingNummer.ToString() == ouderGegevens[2]).FirstOrDefault();
if (gevondenLeerling != null)
{
ouders.Add(new Guardian
{
Email = ouderObject.verzorgerEmail,
FirstName = ouderObject.verzorgerVoorletters,
LastName = ouderObject.verzorgerAchternaam,
Phone = ouderObject.verzorgerMobielNummerGeheim || String.IsNullOrEmpty(ouderObject.verzorgerMobielNummer) ? (ouderObject.verzorgerAdresTelefoonNummerGeheim || String.IsNullOrEmpty(ouderObject.verzorgerAdresTelefoonNummer) ? (ouderObject.verzorgerMobielWerkNummerGeheim || String.IsNullOrEmpty(ouderObject.verzorgerMobielWerkNummer) ? "" : ouderObject.verzorgerMobielWerkNummer) : ouderObject.verzorgerAdresTelefoonNummer) : ouderObject.verzorgerMobielNummer,
//Mobielnummer. Als dit geheim is of niet ingevuld, dan thuisnummer gebruiken.
//Thuisnummer. Als dit geheim is of niet ingevuld, dan werknummer gebruiken.
//Werknummer. Als dit geheim is, geen nummer invullen.
SISid = ouderObject.verzorgerUUID
});
ouderRelaties.Add(new GuardianRelationship
{
Email = ouderObject.verzorgerEmail,
SISid = gevondenLeerling.leerlingNummer.ToString()
});
}
}
}
}
}
}
Console.Write(". ");
Console.WriteLine(ouders.Count);
return Tuple.Create<List<Guardian>, List<GuardianRelationship>>(ouders.GroupBy(o => o.SISid).Select(o => o.FirstOrDefault()).ToList(), ouderRelaties);
}


private string GetFilteredName(string input)
{
//Alles met een spatie of verboden teken voor OneDrive wordt omgezet naar _
string _temp = Regex.Replace(input, @"[^\S]|[\~\""\#\%\&\*\:\<\>\?\/\\{\|}\.]", "_");
string _temp = Regex.Replace(input, @"[^\S]|[\~\""\#\%\&\*\:\<\>\?\/\\{\|}\.\[\]]", "_");
return RemoveDiacritics(_temp);
}

Expand Down
27 changes: 26 additions & 1 deletion Somtoday2MicrosoftSchoolDataSync/Helpers/ServiceHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ServiceHelper
private string umServiceUsername;
private string umServicePassword;
private string umServiceSchooljaar;
EventLogHelper eh = new EventLogHelper();
EventLogHelper eh = Program.eh;

public ServiceHelper(string umServiceBrinNr, string umServiceUsername, string umServicePassword, string umServiceSchooljaar)
{
Expand Down Expand Up @@ -107,6 +107,31 @@ internal List<UserLesgroepModel> GetStudentInfo(List<VestigingLesgroepModel> ves
return _userLesgroepModel;
}

internal List<UserLesgroepModel> GetGuardianInfo(List<VestigingLesgroepModel> vestigingLesgroepModel)
{
Console.WriteLine(string.Format("Oudergegevens opvragen..."));
List<UserLesgroepModel> _userLesgroepModel = new List<UserLesgroepModel>();
using (UmService.UmServiceClient us = new UmService.UmServiceClient())
{
foreach (var vestigingLesgroep in vestigingLesgroepModel)
{
Console.Write(string.Format("Ouders {0}: ", vestigingLesgroep.Vestiging.afkorting));
try
{
List<UmService.webserviceUmObject> ouders = us.getDataVerzorgers(umServiceBrinNr, umServiceUsername, umServicePassword, umServiceSchooljaar, vestigingLesgroep.Vestiging.afkorting).ToList(); ;
Console.WriteLine(string.Format("{0}", ouders.Count()));
_userLesgroepModel.Add(new UserLesgroepModel { Users = ouders, VestigingLesgroep = vestigingLesgroep });
}
catch (Exception ex)
{
eh.WriteLog(String.Format("Ouders download mislukt: {0}", ex.Message), System.Diagnostics.EventLogEntryType.Error, 500);
}
}
}
Console.WriteLine();
return _userLesgroepModel;
}

internal List<UserLesgroepModel> GetTeacherInfo(List<VestigingLesgroepModel> vestigingLesgroepModel)
{
Console.WriteLine(string.Format("Medewerkergegevens opvragen..."));
Expand Down
Loading

0 comments on commit e10c59d

Please sign in to comment.