fix: Anwesenheitskalender/Fehltagesliste nutzen die real deklarierte Boxgröße
CI / build-and-test (push) Waiting to run
CI / build-and-test (push) Waiting to run
Die DrawingValue-Builder gingen bisher immer von einer festen Breite (170) aus, unabhängig davon, wie breit die DRAWBOX/FLOWDRAWBOX in der jeweiligen Vorlage tatsächlich deklariert ist. Bei einer breiteren Box (oder einer in "pt" statt "mm" deklarierten Seite, wie im echten Fehlzeitenbrief-Template) blieb dadurch ein Großteil der eigentlich verfügbaren Fläche ungenutzt leer - sichtbar als "Luft" rechts und unterhalb des Kalenders im generierten PDF. CreateLetterDialogViewModel/LetterTemplateTools ermitteln jetzt die real deklarierte Boxbreite samt Maßeinheit aus dem geladenen Template (LetterPlaceholderBuilder.FindDeclaredDrawingBox) und reichen sie an die Builder durch, die ihr mm-entworfenes Raster entsprechend skalieren. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -62,7 +62,7 @@ public sealed class CreateLetterDialogViewModelTests : IDisposable
|
||||
StudentAttendanceCalendarDrawingBuilder.PlaceholderName, PlaceholderType.Drawing, true));
|
||||
var drawing = StudentAttendanceCalendarDrawingBuilder.Build("Lena Beispiel", new DateOnly(2026, 9, 1), [], []);
|
||||
var vm = new CreateLetterDialogViewModel(StudentWithContact("Sehr geehrte Frau Muster,"), store,
|
||||
new QuestTemplateRenderer(), new FakeMemberships([]), new FakeGroups([]), _ => drawing);
|
||||
new QuestTemplateRenderer(), new FakeMemberships([]), new FakeGroups([]), (_, _, _) => drawing);
|
||||
var output = Path.Combine(_directory, "Kalender.pdf");
|
||||
|
||||
Assert.True(vm.UsesAttendanceCalendar);
|
||||
@@ -76,6 +76,67 @@ public sealed class CreateLetterDialogViewModelTests : IDisposable
|
||||
Assert.Equal("%PDF", System.Text.Encoding.ASCII.GetString(File.ReadAllBytes(output), 0, 4));
|
||||
}
|
||||
|
||||
// Regression: Der DrawingValue-Builder hat früher immer eine feste Breite (170) angenommen,
|
||||
// unabhängig davon, wie breit die DRAWBOX in der jeweiligen Vorlage tatsächlich deklariert war -
|
||||
// bei breiteren (oder in "pt" statt "mm" deklarierten) Boxen blieb dadurch ein Großteil der
|
||||
// eigentlich verfügbaren Fläche ungenutzt leer (sichtbar in echten Elternbriefen als "Luft"
|
||||
// rechts/unterhalb des Kalenders). Der Dialog muss die real deklarierte Breite ermitteln und an
|
||||
// den Builder weiterreichen.
|
||||
[Fact]
|
||||
public void AdvancedContent_Anwesenheitskalender_NutztDieImLayoutDeklarierteBoxbreite()
|
||||
{
|
||||
var manifest = new TemplateManifest
|
||||
{
|
||||
Id = $"brief-{Guid.NewGuid():N}", Name = "Elternbrief",
|
||||
Placeholders = [new(StudentAttendanceCalendarDrawingBuilder.PlaceholderName, PlaceholderType.Drawing, true)],
|
||||
};
|
||||
var source = Path.Combine(_directory, $"{Guid.NewGuid():N}.lavorlage");
|
||||
TemplatePackage.Create(source, manifest,
|
||||
$"PAGE 210 297 mm\nDRAWBOX 20 20 250 80 ${StudentAttendanceCalendarDrawingBuilder.PlaceholderName}",
|
||||
new Dictionary<string, byte[]>());
|
||||
var store = new TemplateStore(Path.Combine(_directory, $"store-{Guid.NewGuid():N}"));
|
||||
store.Import(source);
|
||||
float? receivedWidth = null; float? receivedMillimeterScale = null;
|
||||
|
||||
var vm = new CreateLetterDialogViewModel(StudentWithContact("Sehr geehrte Frau Muster,"), store,
|
||||
new QuestTemplateRenderer(), new FakeMemberships([]), new FakeGroups([]),
|
||||
(_, width, millimeterScale) => { receivedWidth = width; receivedMillimeterScale = millimeterScale; return new DrawingValue([], 0); });
|
||||
|
||||
Assert.True(vm.UsesAttendanceCalendar);
|
||||
Assert.Equal(250, receivedWidth);
|
||||
Assert.Equal(1, receivedMillimeterScale);
|
||||
}
|
||||
|
||||
// Regression: Eine reale, aus einem Word-Dokument übernommene Vorlage deklariert die Seite in
|
||||
// "pt" statt "mm" (PAGE ... pt). Ohne Umrechnung würde das mm-entworfene Kalenderraster dort nur
|
||||
// rund ein Drittel der vorgesehenen physischen Größe erreichen (1 "mm-Einheit" würde als 1pt statt
|
||||
// als ~2.83pt gerendert).
|
||||
[Fact]
|
||||
public void AdvancedContent_Anwesenheitskalender_RechnetBoxbreiteBeiPunktBasierterVorlageUm()
|
||||
{
|
||||
var manifest = new TemplateManifest
|
||||
{
|
||||
Id = $"brief-{Guid.NewGuid():N}", Name = "Elternbrief",
|
||||
Placeholders = [new(StudentAttendanceCalendarDrawingBuilder.PlaceholderName, PlaceholderType.Drawing, true)],
|
||||
};
|
||||
var source = Path.Combine(_directory, $"{Guid.NewGuid():N}.lavorlage");
|
||||
TemplatePackage.Create(source, manifest,
|
||||
$"PAGE 595.32 841.92 pt\nDRAWBOX 71 350 487 177 ${StudentAttendanceCalendarDrawingBuilder.PlaceholderName}",
|
||||
new Dictionary<string, byte[]>());
|
||||
var store = new TemplateStore(Path.Combine(_directory, $"store-{Guid.NewGuid():N}"));
|
||||
store.Import(source);
|
||||
float? receivedWidth = null; float? receivedMillimeterScale = null;
|
||||
|
||||
var vm = new CreateLetterDialogViewModel(StudentWithContact("Sehr geehrte Frau Muster,"), store,
|
||||
new QuestTemplateRenderer(), new FakeMemberships([]), new FakeGroups([]),
|
||||
(_, width, millimeterScale) => { receivedWidth = width; receivedMillimeterScale = millimeterScale; return new DrawingValue([], 0); });
|
||||
|
||||
Assert.True(vm.UsesAttendanceCalendar);
|
||||
Assert.Equal(487, receivedWidth);
|
||||
Assert.NotNull(receivedMillimeterScale);
|
||||
Assert.Equal(2.8346f, receivedMillimeterScale!.Value, 0.001f);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttendanceKalenderKonfigurieren_LoestGezieltenDatenAbrufFuerDenZeitraumAus()
|
||||
{
|
||||
@@ -84,7 +145,7 @@ public sealed class CreateLetterDialogViewModelTests : IDisposable
|
||||
AttendanceCalendarOptions? requested = null;
|
||||
var vm = new CreateLetterDialogViewModel(StudentWithContact("Sehr geehrte Frau Muster,"), store,
|
||||
new QuestTemplateRenderer(), new FakeMemberships([]), new FakeGroups([]),
|
||||
_ => new DrawingValue([], 0), attendanceDataRefresher: (options, _) =>
|
||||
(_, _, _) => new DrawingValue([], 0), attendanceDataRefresher: (options, _) =>
|
||||
{ requested = options; return Task.CompletedTask; });
|
||||
|
||||
await vm.SetAttendanceCalendarOptionsAsync(new AttendanceCalendarOptions(
|
||||
@@ -104,7 +165,7 @@ public sealed class CreateLetterDialogViewModelTests : IDisposable
|
||||
StudentAttendanceCalendarDrawingBuilder.PlaceholderName, PlaceholderType.Drawing, true));
|
||||
var vm = new CreateLetterDialogViewModel(StudentWithContact("Sehr geehrte Frau Muster,"), store,
|
||||
new QuestTemplateRenderer(), new FakeMemberships([]), new FakeGroups([]),
|
||||
_ => new DrawingValue([], 0),
|
||||
(_, _, _) => new DrawingValue([], 0),
|
||||
attendanceDataRefresher: (_, _) => throw new WebUntisIntegrationException("Keine Verbindung."));
|
||||
|
||||
await vm.SetAttendanceCalendarOptionsAsync(new AttendanceCalendarOptions(
|
||||
@@ -124,7 +185,7 @@ public sealed class CreateLetterDialogViewModelTests : IDisposable
|
||||
new AttendanceCalendarOptions(new DateOnly(2026, 9, 1), 1), []);
|
||||
var vm = new CreateLetterDialogViewModel(StudentWithContact("Sehr geehrte Frau Muster,"), store,
|
||||
new QuestTemplateRenderer(), new FakeMemberships([]), new FakeGroups([]),
|
||||
attendanceCalendarFactory: null, absenceDayListFactory: _ => drawing);
|
||||
attendanceCalendarFactory: null, absenceDayListFactory: (_, _, _) => drawing);
|
||||
|
||||
Assert.False(vm.UsesAttendanceCalendar);
|
||||
Assert.True(vm.UsesAbsenceDayList);
|
||||
|
||||
Reference in New Issue
Block a user