fix(pronote): conserver les annulations ambiguës
This commit is contained in:
@@ -43,16 +43,16 @@ def collapse_replaced_lessons(lessons: list[Lesson]) -> list[Lesson]:
|
|||||||
"""Supprime l'ancien exemplaire annulé lorsqu'un cours déplacé est présent.
|
"""Supprime l'ancien exemplaire annulé lorsqu'un cours déplacé est présent.
|
||||||
|
|
||||||
Deux cours sont considérés comme les exemplaires d'une même modification
|
Deux cours sont considérés comme les exemplaires d'une même modification
|
||||||
lorsqu'ils partagent les dates, la matière, les enseignants et le groupe.
|
lorsqu'ils partagent les dates, la matière, les enseignants et le groupe,
|
||||||
Une annulation isolée est toujours conservée ; seule l'annulation associée
|
et qu'une seule annulation et un seul déplacement se distinguent par leur
|
||||||
à un exemplaire ``MOVED`` est retirée.
|
salle. Une annulation isolée ou ambiguë est toujours conservée.
|
||||||
|
|
||||||
:param lessons: Cours issus d'une source Pronote.
|
:param lessons: Cours issus d'une source Pronote.
|
||||||
:return: Cours consolidés dans leur ordre d'origine.
|
:return: Cours consolidés dans leur ordre d'origine.
|
||||||
:rtype: list[Lesson]
|
:rtype: list[Lesson]
|
||||||
"""
|
"""
|
||||||
grouped: dict[tuple[object, ...], list[Lesson]] = defaultdict(list)
|
grouped: dict[tuple[object, ...], list[tuple[int, Lesson]]] = defaultdict(list)
|
||||||
for lesson in lessons:
|
for index, lesson in enumerate(lessons):
|
||||||
key = (
|
key = (
|
||||||
lesson.start,
|
lesson.start,
|
||||||
lesson.end,
|
lesson.end,
|
||||||
@@ -60,20 +60,13 @@ def collapse_replaced_lessons(lessons: list[Lesson]) -> list[Lesson]:
|
|||||||
tuple(teacher.casefold() for teacher in lesson.teachers),
|
tuple(teacher.casefold() for teacher in lesson.teachers),
|
||||||
(lesson.group or "").casefold(),
|
(lesson.group or "").casefold(),
|
||||||
)
|
)
|
||||||
grouped[key].append(lesson)
|
grouped[key].append((index, lesson))
|
||||||
|
|
||||||
result: list[Lesson] = []
|
replaced_indexes: set[int] = set()
|
||||||
for lesson in lessons:
|
for siblings in grouped.values():
|
||||||
key = (
|
cancelled = [item for item in siblings if item[1].status == LessonStatus.CANCELLED]
|
||||||
lesson.start,
|
moved = [item for item in siblings if item[1].status == LessonStatus.MOVED]
|
||||||
lesson.end,
|
if len(cancelled) == 1 and len(moved) == 1 and cancelled[0][1].rooms != moved[0][1].rooms:
|
||||||
lesson.subject.casefold(),
|
replaced_indexes.add(cancelled[0][0])
|
||||||
tuple(teacher.casefold() for teacher in lesson.teachers),
|
|
||||||
(lesson.group or "").casefold(),
|
return [lesson for index, lesson in enumerate(lessons) if index not in replaced_indexes]
|
||||||
)
|
|
||||||
siblings = grouped[key]
|
|
||||||
has_moved = any(sibling.status == LessonStatus.MOVED for sibling in siblings)
|
|
||||||
if has_moved and lesson.status == LessonStatus.CANCELLED:
|
|
||||||
continue
|
|
||||||
result.append(lesson)
|
|
||||||
return result
|
|
||||||
|
|||||||
@@ -75,3 +75,17 @@ def test_collapse_replaced_lessons_keeps_real_cancellation() -> None:
|
|||||||
cancelled = _lesson(LessonStatus.CANCELLED, "101")
|
cancelled = _lesson(LessonStatus.CANCELLED, "101")
|
||||||
|
|
||||||
assert collapse_replaced_lessons([cancelled]) == [cancelled]
|
assert collapse_replaced_lessons([cancelled]) == [cancelled]
|
||||||
|
|
||||||
|
|
||||||
|
def test_collapse_replaced_lessons_keeps_ambiguous_cancellations() -> None:
|
||||||
|
"""Conserve les annulations lorsqu'une paire de remplacement est ambiguë.
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
cancelled_old = _lesson(LessonStatus.CANCELLED, "101")
|
||||||
|
cancelled_real = _lesson(LessonStatus.CANCELLED, "305")
|
||||||
|
moved = _lesson(LessonStatus.MOVED, "204")
|
||||||
|
|
||||||
|
result = collapse_replaced_lessons([cancelled_old, cancelled_real, moved])
|
||||||
|
|
||||||
|
assert result == [cancelled_old, cancelled_real, moved]
|
||||||
|
|||||||
Reference in New Issue
Block a user