Klassenlehrer: Fehlquote nutzt echten WebUntis-Ferienkalender + Sommerferien-Näherung, Diagnose-Logging
CI / build-and-test (push) Canceled after 0s
CI / build-and-test (push) Canceled after 0s
Nutzer-Verifikation deckte auf, dass WebUntis' getHolidays für dieses Konto nie einen Sommerferien-Eintrag liefert (11 Jahre Kontohistorie geprüft, kein einziger Juli-/August-Zeitraum dabei) - vermutlich weil die Sommerferien WebUntis-intern zwischen zwei Schuljahres-Datensätzen liegen statt in einem. Die reine Ferienkalender-Abfrage aus dem letzten Commit kann diese Lücke also nicht schließen: der frühere heuristische Ansatz (frühester Fehlzeiten-Eintrag der Klasse als Näherung für den ersten Unterrichtstag) ist deshalb zusätzlich wieder da, kombiniert mit dem echten Ferienkalender für den Rest des Jahres. Herkunft des Nenners jetzt im Tooltip sichtbar (angenommener Unterrichtsbeginn, abgezogene Ferientage) statt nur intern verrechnet, plus Logging jedes Ferienabrufs (Erfolg oder Fehler) - sonst wäre der falsche Wert wieder unbemerkt geblieben. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -184,7 +184,8 @@ public sealed class ClassTeacherViewModelsTests
|
||||
};
|
||||
|
||||
var row = Assert.Single(ClassTeacherRosterRow.Build(students, [], [],
|
||||
new DateOnly(2026, 8, 26), yearAbsences, schoolDaysElapsed: 20));
|
||||
new DateOnly(2026, 8, 26), yearAbsences, schoolDaysElapsed: 20,
|
||||
termStart: new DateOnly(2026, 8, 1)));
|
||||
|
||||
Assert.True(row.HasYearSummary);
|
||||
Assert.Equal(2, row.YearAbsenceDayCount);
|
||||
@@ -192,9 +193,29 @@ public sealed class ClassTeacherViewModelsTests
|
||||
Assert.Equal(10, row.YearAbsenceRatePercent);
|
||||
Assert.Contains("10 %", row.YearSummaryLabel);
|
||||
Assert.Contains("2 von 20", row.YearSummaryTooltip);
|
||||
Assert.Contains("seit 01.08.", row.YearSummaryTooltip);
|
||||
Assert.Contains("1 unentschuldigt", row.YearSummaryTooltip);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RosterBuild_ZeigtAbgezogeneFerientageImTooltip()
|
||||
{
|
||||
// Nutzer-Nachfrage: die Herkunft des Nenners soll sich ohne Blick in die WebUntis-Ferienliste
|
||||
// direkt in der App nachvollziehen lassen, nachdem er zeitweise Ferientage mitzählte.
|
||||
var students = new[] { Student(1001, "Ada Müller") };
|
||||
var yearAbsences = new[]
|
||||
{
|
||||
new ClassAbsenceDaySummaryRow(new DateOnly(2026, 8, 17), "Müller Ada", 1001, 2, 90,
|
||||
["Che"], [1, 2], ["entsch."], ["Krank"], null, null, false),
|
||||
};
|
||||
|
||||
var row = Assert.Single(ClassTeacherRosterRow.Build(students, [], [],
|
||||
new DateOnly(2026, 8, 26), yearAbsences, schoolDaysElapsed: 14, holidayWeekdaysExcluded: 7,
|
||||
termStart: new DateOnly(2026, 8, 1)));
|
||||
|
||||
Assert.Contains("7 Ferientage abgezogen", row.YearSummaryTooltip);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RosterBuild_OhneJahresdatenZeigtKeineFehlquote()
|
||||
{
|
||||
@@ -290,6 +311,53 @@ public sealed class ClassTeacherViewModelsTests
|
||||
Assert.Equal(21, schoolDays);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EstimateTermStart_NutztFruehestenFehlzeitEintragDerGanzenKlasse()
|
||||
{
|
||||
// Realer Befund (Nutzer-Feedback): WebUntis' getHolidays liefert für Bremen nie einen
|
||||
// Sommerferien-Eintrag (über 11 Jahre Kontohistorie geprüft, kein einziger Juli-/August-
|
||||
// Zeitraum dabei) - vermutlich weil die Sommerferien WebUntis-intern zwischen zwei
|
||||
// Schuljahres-Datensätzen liegen (1.8./31.7.-Grenze), nicht "in" einem davon. Für den
|
||||
// Schuljahresbeginn bleibt deshalb weiterhin der früheste Fehlzeiten-Eintrag der Klasse
|
||||
// nötig statt CountSchoolWeekdays allein.
|
||||
var absences = new[]
|
||||
{
|
||||
new ClassAbsenceDaySummaryRow(new DateOnly(2026, 8, 13), "Fehlt Cem", 1001, 1, 45,
|
||||
["Deu"], [1], ["nicht entsch."], ["Absent"], null, null, false),
|
||||
new ClassAbsenceDaySummaryRow(new DateOnly(2026, 8, 19), "Andere Ada", 1002, 1, 45,
|
||||
["Deu"], [1], ["entsch."], ["Absent"], null, null, false),
|
||||
};
|
||||
|
||||
var termStart = ClassTeacherOverviewViewModel.EstimateTermStart(absences, new DateOnly(2026, 8, 1));
|
||||
|
||||
Assert.Equal(new DateOnly(2026, 8, 13), termStart);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EstimateTermStart_FaelltOhneFehlzeitenAufSchuljahresbeginnZurueck()
|
||||
{
|
||||
var termStart = ClassTeacherOverviewViewModel.EstimateTermStart([], new DateOnly(2026, 8, 1));
|
||||
|
||||
Assert.Equal(new DateOnly(2026, 8, 1), termStart);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CountSchoolWeekdays_AbEchtemTerminstartOhneSommerferienEintragStimmtMitBeobachtungUeberein()
|
||||
{
|
||||
// Regressionstest für den konkret gemeldeten Fall: 13 tatsächliche Schultage seit
|
||||
// Unterrichtsbeginn (13.08.2026, ein Donnerstag) bis 31.08.2026, keine WebUntis-Ferien im
|
||||
// Bereich (die nächste, "Herbstferien", liegt erst im Oktober) - Kombination aus
|
||||
// EstimateTermStart (Sommerferien-Lücke) und CountSchoolWeekdays (übrige Ferien) muss auf
|
||||
// die vom Nutzer nachgezählte Zahl kommen, nicht auf die volle Werktagszahl ab 1.8. (21).
|
||||
var termStart = new DateOnly(2026, 8, 13);
|
||||
var noHolidaysInRange = Array.Empty<CachedUntisHoliday>();
|
||||
|
||||
var schoolDays = ClassTeacherOverviewViewModel.CountSchoolWeekdays(
|
||||
termStart, new DateOnly(2026, 8, 31), noHolidaysInRange);
|
||||
|
||||
Assert.Equal(13, schoolDays);
|
||||
}
|
||||
|
||||
// ── Offene Entschuldigungen (Feature-Idee 2) ─────────────────────────────
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user