Fix unit persistence before saving timetable lessons
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
admin committed 2026-11-09 21:50:36 +01:00
1 parent cbcb739097
commit fb38b6bb04
5 files changed
+53 -1

No files matched your search

@@ -8,6 +8,43 @@ namespace LehrerApp.Desktop.Tests;
public sealed class LessonDialogViewModelTests
{
[Fact]
public void Save_PersistsParentBeforeLesson()
{
var lessons = new FakeLessons();
var unitId = Guid.NewGuid();
var vm = new LessonDialogViewModel(lessons, new FakeShorthandCodes([]),
new FakeAlternativeLessonPaths([]), new FakeTimetableSlots(), NewPeriodSchedule(),
new FakeAttachmentStorage(), unitId, Guid.NewGuid(), "10c", "Chemie", [], [], null);
vm.Topic = "Test";
vm.DateText = "09.11.2026";
var called = false;
vm.BeforeSave = () =>
{
Assert.Empty(lessons.GetByUnit(unitId));
called = true;
};
vm.SaveCommand.Execute(null);
Assert.True(called);
Assert.Equal(unitId, Assert.Single(lessons.GetByUnit(unitId)).UnitId);
}
[Fact]
public void Save_InvalidInputDoesNotPersistParent()
{
var vm = BuildVm(Guid.NewGuid(), Guid.NewGuid());
var called = false;
vm.BeforeSave = () => called = true;
vm.DateText = "invalid";
vm.SaveCommand.Execute(null);
Assert.False(called);
Assert.Null(vm.Result);
}
private static PeriodScheduleService NewPeriodSchedule()
{
var tempPath = System.IO.Path.Combine(
@@ -789,6 +789,10 @@ public partial class LessonDialogViewModel : ObservableObject
// Für die KI-Unterstützung mit Fokus auf genau diese Stunde (4.5.22) — nur für bereits
// gespeicherte Stunden sinnvoll, eine gerade erst angelegte, noch ungespeicherte Stunde hat
// keine echte Id, auf die sich die KI beziehen könnte.
// Persist a pending parent only after validation and before writing its first lesson.
public Action? BeforeSave { get; set; }
public void EnsureParentSaved() => BeforeSave?.Invoke();
public Guid UnitId => _unitId;
public Guid GroupId => _groupId;
public Lesson? EditingLesson => _editingLesson;
@@ -1079,6 +1083,7 @@ public partial class LessonDialogViewModel : ObservableObject
if (!valid) return;
EnsureParentSaved();
Result = _editingLesson ?? new Lesson { UnitId = _unitId, GroupId = _groupId };
Result.UnitId = _unitId;
Result.GroupId = _groupId;
@@ -265,6 +265,7 @@ public partial class LessonDialog : Window
chosen = picked;
}
vm.EnsureParentSaved();
chosen.UnitId = vm.UnitId;
chosen.Date = date;
chosen.LessonNumber = vm.LessonNumber;
@@ -121,10 +121,14 @@ public partial class TimetableView : UserControl
App.Services.GetRequiredService<IAttachmentStorage>(),
unit.Id, group.Id, group.Name, subject?.Name ?? "", materials, shorthands,
editingLesson: null, suggestedDate: request.Date, suggestedPeriod: request.PeriodNumber);
if (pickerVm.ResultIsNew)
lessonVm.BeforeSave = () =>
{
if (units.GetById(unit.Id) is null) units.Save(unit);
};
var lessonDialog = new LessonDialog { DataContext = lessonVm };
if (await lessonDialog.ShowDialog<bool>(owner) && lessonVm.Result is not null)
{
if (pickerVm.ResultIsNew) units.Save(unit);
(DataContext as TimetableViewModel)?.Load();
App.Services.GetRequiredService<NotificationService>().ShowSuccess("Stunde angelegt.");
}
+5
View File
@@ -2541,6 +2541,11 @@ zurückgestellt):
vorgeschalteter Dialog sortiert laufende Einheiten zuerst, lässt aber auch direkt eine neue
Einheit anlegen; damit ist die frühere offene Unit-Frage ohne stillschweigende Zuordnung gelöst.
Neue Direktanlagen starten als `Entwurf`.
Nachtrag (09.11.2026): Neue Einheit erst nach erfolgreicher Eingabevalidierung, aber vor
der ersten Stunde speichern (auch beim Verknuepfen einer vorhandenen Stunde). Damit
entfaellt das verwaiste Zeitfenster bis zum Schliessen des Dialogs; Abbruch bleibt ohne
neue Einheit. 119 betroffene Desktop-Tests bestanden. Bereits verwaiste Stunden werden
dadurch nicht automatisch neu zugeordnet.
- [x] **4.5.3** Aus diesem Lesson-Viewer heraus weiter verzweigen können: in die Zeugnisnote/
Bewertung der Gruppe, und in die Schnelldialoge für Mitarbeit sowie Anwesenheit/Hausaufgaben.
**Umsetzung:** Zwei neue Buttons im Footer von `LessonViewerDialog` ("Zur Mitarbeit"/