fix: Fehlzeitenkalender in Templates
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
2026-09-16 00:50:10 +02:00
parent 6e57bf407d
commit 6dccf96039
7 changed files with 166 additions and 42 deletions
+18 -1
View File
@@ -22,10 +22,27 @@ public static class LetterDialogs
App.Services.GetRequiredService<IGroupRepository>(),
options => App.Services.GetRequiredService<StudentAttendanceCalendarService>().Build(student, options),
options => App.Services.GetRequiredService<StudentAttendanceCalendarService>()
.BuildAbsenceDayList(student, options));
.BuildAbsenceDayList(student, options),
RefreshAttendanceDataAsync);
var dialog = new CreateLetterDialog { DataContext = vm };
var path = await dialog.ShowDialog<string?>(owner);
if (!string.IsNullOrEmpty(path) && File.Exists(path))
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(path) { UseShellExecute = true });
}
/// <summary>Holt genau den im Anwesenheitskalender-Dialog gewählten Zeitraum gezielt per
/// WebUntis nach (ausgelöst durch den expliziten "Konfigurieren…"-Klick, kein Hintergrundabruf
/// beim bloßen Öffnen des Briefdialogs). Damit sieht <see cref="StudentAttendanceCalendarService"/>
/// anschließend frische Daten im lokalen Cache, statt stillschweigend "keine Fehltage" zu
/// melden, nur weil die Klassenlehrer-Übersicht für diesen Zeitraum noch nie geöffnet wurde.</summary>
private static async Task RefreshAttendanceDataAsync(AttendanceCalendarOptions options, CancellationToken token)
{
var className = App.Services.GetRequiredService<WebUntisSettingsService>().HomeroomClassName;
if (string.IsNullOrWhiteSpace(className)) return;
var cache = App.Services.GetRequiredService<UntisReportCacheService>();
var start = options.NormalizedStartMonth;
var end = start.AddMonths(options.NormalizedMonthCount).AddDays(-1);
await cache.GetAbsencesAsync(className, start, end, token: token);
await cache.GetClassRegisterEventsAsync(className, start, end, token: token);
}
}
@@ -26,6 +26,7 @@ public static class LetterPlaceholderBuilder
["Empfaenger"] = new TextValue(contact?.Name ?? ""), ["Anrede"] = new TextValue(contact?.LetterSalutation ?? ""),
["Brieftext"] = new MultilineValue(letterText), ["LehrerName"] = new TextValue(teacherName),
["Student.FirstName"] = new TextValue(student.FirstName), ["Student.LastName"] = new TextValue(student.LastName),
["Student.Name"] = new TextValue(student.FullName),
["Contact.Name"] = new TextValue(contact?.Name ?? ""), ["Contact.Address"] = new MultilineValue(address),
["Contact.Street"] = new TextValue(contact?.Street ?? ""), ["Contact.PostalCode"] = new TextValue(contact?.PostalCode ?? ""),
["Contact.City"] = new TextValue(contact?.City ?? ""), ["Letter.Salutation"] = new TextValue(contact?.LetterSalutation ?? ""),
@@ -43,15 +43,15 @@ public static class StudentAttendanceCalendarDrawingBuilder
var monthGap = 6 * scale;
var first = options.NormalizedStartMonth;
var monthCount = options.NormalizedMonthCount;
var commands = new List<DrawingCommand>
{
new DrawStringEx(0, 0, 7 * scale, contentWidth, "Anwesenheit",
DrawingTextAlignment.AlignLeft, 11 * scale, Color: "#1F2937", Bold: true),
new DrawStringEx(0, 7 * scale, 6 * scale, contentWidth, studentName,
DrawingTextAlignment.AlignLeft, 8 * scale, Color: "#6B7280"),
};
var commands = new List<DrawingCommand>();
var y = 0f;
commands.Add(new DrawStringEx(0, y, 14 * scale, contentWidth, "Anwesenheit",
DrawingTextAlignment.AlignLeft, 11 * scale, Color: "#1F2937", Bold: true));
y += 14 * scale;
commands.Add(new DrawStringEx(0, y, 10 * scale, contentWidth, studentName,
DrawingTextAlignment.AlignLeft, 8 * scale, Color: "#6B7280"));
y += 10 * scale + 2 * scale;
var weekdays = new[] { "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So" };
var y = 15 * scale;
for (var monthIndex = 0; monthIndex < monthCount; monthIndex++)
{
var current = first.AddMonths(monthIndex);
@@ -59,14 +59,14 @@ public static class StudentAttendanceCalendarDrawingBuilder
DateOnly.FromDateTime(DateTime.Today), studentName);
var offset = ((int)current.DayOfWeek + 6) % 7;
var weeks = (int)Math.Ceiling((offset + days.Count) / 7d);
commands.Add(new DrawStringEx(0, y, 7 * scale, contentWidth,
commands.Add(new DrawStringEx(0, y, 11 * scale, contentWidth,
current.ToString("MMMM yyyy", CultureInfo.GetCultureInfo("de-DE")),
DrawingTextAlignment.AlignLeft, 9 * scale, Color: "#374151", Bold: true));
y += 7 * scale;
y += 11 * scale;
for (var column = 0; column < 7; column++)
commands.Add(new DrawStringEx(column * cellWidth, y, 6 * scale, cellWidth, weekdays[column],
commands.Add(new DrawStringEx(column * cellWidth, y, 9 * scale, cellWidth, weekdays[column],
DrawingTextAlignment.AlignCenter, 7 * scale, Color: "#6B7280", Bold: true));
y += 7 * scale;
y += 9 * scale;
foreach (var day in days)
{
@@ -115,20 +115,20 @@ public static class StudentAbsenceDayListDrawingBuilder
UntisNameMatching.NamesMatch(a.StudentName, studentName))
.OrderBy(a => a.Date)
.ToList();
var commands = new List<DrawingCommand>
{
new DrawStringEx(0, 0, 7 * scale, contentWidth, "Fehltage",
DrawingTextAlignment.AlignLeft, 11 * scale, Color: "#1F2937", Bold: true),
new DrawStringEx(0, 7 * scale, 6 * scale, contentWidth, studentName,
DrawingTextAlignment.AlignLeft, 8 * scale, Color: "#6B7280"),
};
var y = 16 * scale;
var commands = new List<DrawingCommand>();
var y = 0f;
commands.Add(new DrawStringEx(0, y, 14 * scale, contentWidth, "Fehltage",
DrawingTextAlignment.AlignLeft, 11 * scale, Color: "#1F2937", Bold: true));
y += 14 * scale;
commands.Add(new DrawStringEx(0, y, 10 * scale, contentWidth, studentName,
DrawingTextAlignment.AlignLeft, 8 * scale, Color: "#6B7280"));
y += 10 * scale + 2 * scale;
commands.Add(new DrawRectangle(0, y, contentWidth, rowHeight, "#CBD5E1", .4f, "#F3F4F6"));
commands.Add(new DrawStringEx(2 * scale, y + scale, rowHeight - 2 * scale, 31 * scale, "Datum",
commands.Add(new DrawStringEx(2 * scale, y + scale, rowHeight - scale, 31 * scale, "Datum",
DrawingTextAlignment.AlignLeft, 7.5f * scale, Color: "#374151", Bold: true));
commands.Add(new DrawStringEx(36 * scale, y + scale, rowHeight - 2 * scale, 75 * scale, "Umfang",
commands.Add(new DrawStringEx(36 * scale, y + scale, rowHeight - scale, 75 * scale, "Umfang",
DrawingTextAlignment.AlignLeft, 7.5f * scale, Color: "#374151", Bold: true));
commands.Add(new DrawStringEx(113 * scale, y + scale, rowHeight - 2 * scale, 55 * scale, "Status",
commands.Add(new DrawStringEx(113 * scale, y + scale, rowHeight - scale, 55 * scale, "Status",
DrawingTextAlignment.AlignLeft, 7.5f * scale, Color: "#374151", Bold: true));
y += rowHeight;
@@ -157,12 +157,12 @@ public static class StudentAbsenceDayListDrawingBuilder
: row.FriendlyStatusLabel;
var statusColor = row.IsUnexcused ? "#C62828" : "#2E7D32";
commands.Add(new DrawRectangle(0, y, contentWidth, rowHeight, "#E5E7EB", .3f, fill));
commands.Add(new DrawStringEx(2 * scale, y + scale, rowHeight - 2 * scale, 31 * scale,
commands.Add(new DrawStringEx(2 * scale, y + scale, rowHeight - scale, 31 * scale,
row.Date.ToString("dd.MM.yyyy"), DrawingTextAlignment.AlignLeft, 7.5f * scale,
Color: "#374151"));
commands.Add(new DrawStringEx(36 * scale, y + scale, rowHeight - 2 * scale, 75 * scale,
commands.Add(new DrawStringEx(36 * scale, y + scale, rowHeight - scale, 75 * scale,
extent, DrawingTextAlignment.AlignLeft, 7.5f * scale, Color: "#374151"));
commands.Add(new DrawStringEx(113 * scale, y + scale, rowHeight - 2 * scale, 55 * scale,
commands.Add(new DrawStringEx(113 * scale, y + scale, rowHeight - scale, 55 * scale,
status, DrawingTextAlignment.AlignLeft, 7.5f * scale, Color: statusColor,
Bold: row.IsUnexcused));
y += rowHeight;