Klassenbucheinträge abgleich und poll

This commit is contained in:
2026-08-25 09:31:41 +02:00
parent 87a7badb44
commit 7fa8a93c82
14 changed files with 584 additions and 9 deletions
+27
View File
@@ -148,6 +148,33 @@ public sealed class WebUntisClient : IAsyncDisposable
return WebUntisLessonAbsenceParser.Parse(reportText);
}, cancellationToken);
// Undokumentierter interner Bericht der WebUntis-WebApp für Klassenbucheinträge ("-alle-"-Bereich,
// damit auch Einträge zu fremden Klassen aus dem eigenen Unterricht mit dabei sind - die
// Oberfläche bietet sonst nur "eigene Klasse" oder "-alle-" an). klasseOrStudentgroupId/
// studentId=-1 entspricht "-alle-" und wird lokal auf eigene Lerngruppen gefiltert.
// Query-Parameter 1:1 aus einem echten Browser-Request übernommen (bis auf das nicht benötigte
// selectedDateRange/_csrf, siehe GetLessonAbsencesAsync). Anders als AbsencePerLesson liefert
// dieser Bericht keine externe Schülerkennung, nur den Namen (siehe UntisClassRegisterEventReportEntry).
public Task<IReadOnlyList<UntisClassRegisterEventReportEntry>> GetClassRegisterEventsReportAsync(
int startDate, int endDate, CancellationToken cancellationToken) => WithSessionAsync(async sessionId =>
{
var query = "name=ClassregEventPerStudent&format=csv&klasseOrStudentgroupId=-1&studentId=-1" +
"&calendarChange=0&withAbsences=true&_withAbsences=on&withLateness=true&_withLateness=on" +
"&excludeNotCountingAbsences=true&_excludeNotCountingAbsences=on&_allStudents=on" +
"&absStudGroup=1&studExcuseStatusId=-1&_withoutPageBreaksAbsPerStudent=on&absClassGroup=1" +
"&classExcuseStatusId=-1&_absClassSorted=on&_separateAbsentDays=on&_filterAbsencesKlasse=on" +
"&absSubjectGroup=7&absSubjectId=-1&absSubjectGroupGroup=7&subjectGroupId=-1&_totalDays=on" +
"&absentPeriodsLimit=16&reportWeeks=4&dayLimit=3&excuseGroup=1&_groupPerWeek=on" +
"&_excuseStatusAll=on&studEventReasonId=-1&classEventReasonId=-1&_evntClassSorted=on" +
"&_withoutPageBreaks=on&withStudentAbsences=true&_withStudentAbsences=on" +
"&examinationTypeId=-1&teachingMethodId=-1&examTypeId=-1&_usingMarkNames=on" +
$"&rpt_sd={startDate}&rpt_ed={endDate}&rpt_syid=-1&rpt_drdtype=CUSTOM";
var reportData = await RequestReportAsync(sessionId, query, cancellationToken)
?? await PollReportAsync(sessionId, cancellationToken);
var reportText = await FetchReportTextAsync(sessionId, reportData, cancellationToken);
return WebUntisClassRegisterEventReportParser.Parse(reportText);
}, cancellationToken);
public Task<IReadOnlyList<UntisSubstitution>> GetSubstitutionsAsync(int startDate, int endDate,
int? departmentId, CancellationToken cancellationToken) => WithSessionAsync(async sessionId =>
{