diff --git a/LehrerApp.Desktop.Tests/SeatingPlanViewModelTests.cs b/LehrerApp.Desktop.Tests/SeatingPlanViewModelTests.cs
index ea67586..571e333 100644
--- a/LehrerApp.Desktop.Tests/SeatingPlanViewModelTests.cs
+++ b/LehrerApp.Desktop.Tests/SeatingPlanViewModelTests.cs
@@ -543,6 +543,50 @@ public sealed class SeatingPlanViewModelTests
Assert.Equal(session.Id, vm.SelectedSession?.Id);
}
+ [Fact]
+ public async Task AssessStudent_SitzungBereitsUeberAndereInstanzVerknuepft_LegtKeineZweiteAn()
+ {
+ // Regressionstest: Der Unterrichtsmodus läuft auf einer eigenen, per DI frisch aufgelösten
+ // SeatingPlanTabViewModel-Instanz (TimetableView.ShowTeachingMode), getrennt von der
+ // Instanz im Sitzplan-Tab der Kursübersicht — beide teilen sich nur das Repository. Wurde
+ // (wie hier simuliert) die Sitzung bereits über den Unterrichtsmodus mit der Stunde
+ // verknüpft, bevor im echten Sitzplan-Tab bewertet wird, darf letzterer keine zweite,
+ // unverknüpfte "Sitzplan"-Sitzung für denselben Tag anlegen.
+ var groupId = Guid.NewGuid();
+ var student = new Student { FirstName = "Anna", LastName = "A" };
+ var plan = new SeatingPlan
+ {
+ GroupId = groupId, Name = "Standard", Rows = 1, Columns = 1,
+ Assignments = [new SeatAssignment { StudentId = student.Id }],
+ };
+ var sessions = new FakeSessions([]);
+ var memberships = new FakeMemberships([new GroupMembership { GroupId = groupId, StudentId = student.Id }]);
+
+ // Instanz A: Sitzplan-Tab der Kursübersicht, bereits initialisiert (kein SelectedSession).
+ var tabVm = new SeatingPlanTabViewModel(new FakeSeatingPlans([plan]), new FakeStudents([student]),
+ memberships, sessions, new FakeEntries(), new FakeAspects());
+ tabVm.Initialize(groupId, isReadOnly: false);
+ tabVm.OnAssessStudent = _ => Task.CompletedTask;
+
+ // Instanz B: eigene, frische Instanz wie im Unterrichtsmodus — verknüpft die Sitzung mit
+ // der Stunde, ohne dass Instanz A davon erfährt.
+ var lesson = new Lesson { GroupId = groupId, Date = DateOnly.FromDateTime(DateTime.Today), Topic = "Redox" };
+ var teachingModeVm = new SeatingPlanTabViewModel(new FakeSeatingPlans([plan]), new FakeStudents([student]),
+ memberships, sessions, new FakeEntries(), new FakeAspects());
+ teachingModeVm.Initialize(groupId, isReadOnly: false);
+ teachingModeVm.SelectOrCreateSessionForLesson(lesson);
+
+ var linked = Assert.Single(sessions.GetByGroup(groupId));
+ Assert.Equal(lesson.Id, linked.LessonId);
+
+ await tabVm.AssessStudent(tabVm.Seats.Single());
+
+ var session = Assert.Single(sessions.GetByGroup(groupId));
+ Assert.Equal(linked.Id, session.Id);
+ Assert.Equal(lesson.Id, session.LessonId);
+ Assert.Equal(session.Id, tabVm.SelectedSession?.Id);
+ }
+
[Fact]
public void ShuffleSeats_ErzeugtNeuenPlanMitVertauschtenPlaetzenUndBehaeltDenUrsprungsplan()
{
diff --git a/LehrerApp.Desktop/ViewModels/Groups/SeatingPlanViewModels.cs b/LehrerApp.Desktop/ViewModels/Groups/SeatingPlanViewModels.cs
index 1174670..ac15337 100644
--- a/LehrerApp.Desktop/ViewModels/Groups/SeatingPlanViewModels.cs
+++ b/LehrerApp.Desktop/ViewModels/Groups/SeatingPlanViewModels.cs
@@ -93,14 +93,37 @@ public partial class SeatingPlanTabViewModel : ObservableObject
/// Legt bei Bedarf die "Sitzung für heute" an, mit der Sitzplan-Bewertungen/-Markierungen
/// verknüpft werden — aber erst, wenn tatsächlich etwas bewertet/markiert wird (AssessStudent/
/// ToggleSituationTag), nicht schon beim Öffnen des Tabs.
+ ///
+ /// Prüft dabei bewusst gegen das Repository und nicht nur gegen das lokal geladene
+ /// / : Der Unterrichtsmodus
+ /// () läuft auf einer eigenen, per DI frisch
+ /// aufgelösten -Instanz (siehe TimetableView.ShowTeachingMode),
+ /// getrennt von der Instanz, die im Sitzplan-Tab der Kursübersicht hängt. Eine dort bereits
+ /// heute angelegte (ggf. verknüpfte) Sitzung ist dieser Instanz also unbekannt, solange sie nur
+ /// im lokalen Feld nachschaut — das führte dazu, dass eine zweite, unverknüpfte "Sitzplan"-
+ /// Sitzung für denselben Tag entstand, sobald im echten Sitzplan-Tab bewertet wurde.
private ParticipationSessionOption? EnsureTodaySession()
{
if (SelectedSession is not null) return SelectedSession;
if (!IsEditable) return null;
+ var today = DateOnly.FromDateTime(DateTime.Today);
+ var existing = _sessions.GetByGroup(_groupId).FirstOrDefault(s => s.Date == today);
+ if (existing is not null)
+ {
+ var found = TodaySessions.FirstOrDefault(o => o.Id == existing.Id);
+ if (found is null)
+ {
+ found = new ParticipationSessionOption(existing);
+ TodaySessions.Add(found);
+ }
+ SelectedSession = found;
+ return found;
+ }
+
var created = new ParticipationSession
{
- GroupId = _groupId, Date = DateOnly.FromDateTime(DateTime.Today), Comment = "Sitzplan",
+ GroupId = _groupId, Date = today, Comment = "Sitzplan",
};
_sessions.Save(created);
var option = new ParticipationSessionOption(created);