Doppelstunden im Stundenplan korrekt anzeigen
This commit is contained in:
@@ -712,6 +712,31 @@ public sealed class TimetableViewModelTests
|
|||||||
Assert.Equal("1", period2.BadgeText);
|
Assert.Equal("1", period2.BadgeText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Load_Doppelstunde_ZeigtLessonThemaInBeidenKacheln_AuchOhnePhasenUndStundenraster()
|
||||||
|
{
|
||||||
|
var date = DateInCurrentWeek(DayOfWeek.Monday);
|
||||||
|
var group = new LearningGroup { Name = "10c" };
|
||||||
|
var slots = new FakeTimetableSlots();
|
||||||
|
slots.Add(new TimetableSlot { GroupId = group.Id, Weekday = date.DayOfWeek, PeriodNumber = 3 });
|
||||||
|
slots.Add(new TimetableSlot { GroupId = group.Id, Weekday = date.DayOfWeek, PeriodNumber = 4 });
|
||||||
|
var lesson = new Lesson
|
||||||
|
{
|
||||||
|
GroupId = group.Id, Date = date, LessonNumber = 3, Topic = "Werkstoffprüfung",
|
||||||
|
Phases = [],
|
||||||
|
};
|
||||||
|
var lessons = new FakeLessons();
|
||||||
|
lessons.Add(lesson);
|
||||||
|
|
||||||
|
var vm = BuildViewModel(slots, new FakeGroups([group]), lessons: lessons);
|
||||||
|
|
||||||
|
var first = vm.WeekItems.Single(c => c.IsSlotCell && c.Weekday == date.DayOfWeek && c.PeriodNumber == 3);
|
||||||
|
var second = vm.WeekItems.Single(c => c.IsSlotCell && c.Weekday == date.DayOfWeek && c.PeriodNumber == 4);
|
||||||
|
Assert.Equal("Werkstoffprüfung", first.Topic);
|
||||||
|
Assert.Equal("Werkstoffprüfung", second.Topic);
|
||||||
|
Assert.Equal(lesson.Id, second.Lesson?.Id);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Load_KeineAnstehendenFerien_KeinBadge()
|
public void Load_KeineAnstehendenFerien_KeinBadge()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -570,9 +570,10 @@ public partial class TimetableViewModel : ObservableObject
|
|||||||
p.Material?.Contains("Experiment", StringComparison.OrdinalIgnoreCase) == true)) == true;
|
p.Material?.Contains("Experiment", StringComparison.OrdinalIgnoreCase) == true)) == true;
|
||||||
|
|
||||||
/// Eine Doppelstunde wird als eine Lesson an der ersten Periode gespeichert. Für die zweite
|
/// Eine Doppelstunde wird als eine Lesson an der ersten Periode gespeichert. Für die zweite
|
||||||
/// Rasterzelle liefern wir dieselbe Lesson nur dann, wenn der Stundenplan dort unmittelbar
|
/// Rasterzelle liefern wir dieselbe Lesson, wenn der Stundenplan dort unmittelbar mit derselben
|
||||||
/// fortgesetzt wird und der geplante Verlauf länger als die erste Periode ist. Eine exakt an
|
/// Lerngruppe fortgesetzt wird. Das darf nicht von bereits eingetragenen Phasendauern abhängen:
|
||||||
/// der Zielperiode verankerte Lesson hat immer Vorrang.
|
/// Gerade ein früher Entwurf hat oft erst Datum und Thema, gehört aber trotzdem zum kompletten
|
||||||
|
/// Doppelstundenblock. Eine exakt an der Zielperiode verankerte Lesson hat immer Vorrang.
|
||||||
private Lesson? FindLessonForSlot(Guid groupId, DateOnly date, int period)
|
private Lesson? FindLessonForSlot(Guid groupId, DateOnly date, int period)
|
||||||
{
|
{
|
||||||
var lessons = _lessons.GetByGroupAndDate(groupId, date);
|
var lessons = _lessons.GetByGroupAndDate(groupId, date);
|
||||||
@@ -584,14 +585,22 @@ public partial class TimetableViewModel : ObservableObject
|
|||||||
var withoutPeriod = lessons.Where(l => l.LessonNumber is null).ToList();
|
var withoutPeriod = lessons.Where(l => l.LessonNumber is null).ToList();
|
||||||
if (withoutPeriod.Count == 1) return withoutPeriod[0];
|
if (withoutPeriod.Count == 1) return withoutPeriod[0];
|
||||||
|
|
||||||
var previous = lessons.Where(l => l.LessonNumber is int p && p == period - 1)
|
var periodsInBlock = _slots.GetByGroup(groupId)
|
||||||
|
.Where(s => s.Weekday == date.DayOfWeek)
|
||||||
|
.Select(s => s.PeriodNumber)
|
||||||
|
.ToHashSet();
|
||||||
|
|
||||||
|
// Vom angefragten Slot innerhalb desselben lückenlosen Blocks rückwärts zur verankerten
|
||||||
|
// Lesson laufen. Damit funktionieren neben Doppelstunden auch seltene Dreifachblöcke.
|
||||||
|
for (var candidatePeriod = period - 1;
|
||||||
|
periodsInBlock.Contains(candidatePeriod) && periodsInBlock.Contains(candidatePeriod + 1);
|
||||||
|
candidatePeriod--)
|
||||||
|
{
|
||||||
|
var blockLesson = lessons.Where(l => l.LessonNumber == candidatePeriod)
|
||||||
.OrderByDescending(l => l.UpdatedAt).FirstOrDefault();
|
.OrderByDescending(l => l.UpdatedAt).FirstOrDefault();
|
||||||
if (previous?.LessonNumber is not int anchor) return null;
|
if (blockLesson is not null) return blockLesson;
|
||||||
var isConsecutiveSlot = _slots.GetByGroup(groupId)
|
}
|
||||||
.Any(s => s.Weekday == date.DayOfWeek && s.PeriodNumber == period);
|
return null;
|
||||||
var firstPeriodMinutes = _periodSchedule.GetDurationMinutes(anchor);
|
|
||||||
return isConsecutiveSlot && firstPeriodMinutes > 0 &&
|
|
||||||
previous.Phases.Sum(p => p.DurationMinutes) > firstPeriodMinutes ? previous : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>4.5.4: Hat die letzte vor <paramref name="date"/> liegende Lesson dieser Gruppe eine
|
/// <summary>4.5.4: Hat die letzte vor <paramref name="date"/> liegende Lesson dieser Gruppe eine
|
||||||
|
|||||||
Reference in New Issue
Block a user