diff --git a/engine/apps/schedules/quality_score.py b/engine/apps/schedules/quality_score.py index 71194cc5..b152e0cc 100644 --- a/engine/apps/schedules/quality_score.py +++ b/engine/apps/schedules/quality_score.py @@ -1,4 +1,5 @@ import datetime +import enum import itertools from collections import defaultdict from typing import Iterable, Union @@ -6,6 +7,11 @@ from typing import Iterable, Union import pytz +class CommentType(str, enum.Enum): + INFO = "info" + WARNING = "warning" + + # TODO: add "inside working hours score" and "balance outside working hours score" when working hours editor is implemented def get_schedule_quality_score(events: list[dict], days: int) -> dict: # an event is “good” if it's a primary event, not a gap and not empty @@ -22,17 +28,22 @@ def get_schedule_quality_score(events: list[dict], days: int) -> dict: else: total_score = 0 - gaps_comment = "Schedule has gaps" if good_event_score < 1 else "Schedule has no gaps" - if balance_score < 0.8: - balance_comment = "Schedule has balance issues" - elif 0.8 <= balance_score < 1: - balance_comment = "Schedule is well-balanced, but still can be improved" + comments = [] + if good_event_score < 1: + comments.append({"type": CommentType.WARNING, "text": "Schedule has gaps"}) else: - balance_comment = "Schedule is perfectly balanced" + comments.append({"type": CommentType.INFO, "text": "Schedule has no gaps"}) + + if balance_score < 0.8: + comments.append({"type": CommentType.WARNING, "text": "Schedule has balance issues"}) + elif 0.8 <= balance_score < 1: + comments.append({"type": CommentType.INFO, "text": "Schedule is well-balanced, but still can be improved"}) + else: + comments.append({"type": CommentType.INFO, "text": "Schedule is perfectly balanced"}) return { "total_score": score_to_percent(total_score), - "comments": [gaps_comment, balance_comment], + "comments": comments, "overloaded_users": overloaded_users, } diff --git a/engine/apps/schedules/tests/test_quality_score.py b/engine/apps/schedules/tests/test_quality_score.py index f49c4a4c..4d313c27 100644 --- a/engine/apps/schedules/tests/test_quality_score.py +++ b/engine/apps/schedules/tests/test_quality_score.py @@ -53,7 +53,10 @@ def test_get_schedule_score_no_events(get_schedule_quality_response): assert response.json() == { "total_score": 0, - "comments": ["Schedule has gaps", "Schedule is perfectly balanced"], + "comments": [ + {"type": "warning", "text": "Schedule has gaps"}, + {"type": "info", "text": "Schedule is perfectly balanced"}, + ], "overloaded_users": [], } @@ -65,7 +68,10 @@ def test_get_schedule_score_09_05(get_schedule_quality_response): assert response.json() == { "total_score": 27, - "comments": ["Schedule has gaps", "Schedule has balance issues"], + "comments": [ + {"type": "warning", "text": "Schedule has gaps"}, + {"type": "warning", "text": "Schedule has balance issues"}, + ], "overloaded_users": [user1.public_primary_key], } @@ -77,7 +83,10 @@ def test_get_schedule_score_09_09(get_schedule_quality_response): assert response.json() == { "total_score": 51, - "comments": ["Schedule has gaps", "Schedule is well-balanced, but still can be improved"], + "comments": [ + {"type": "warning", "text": "Schedule has gaps"}, + {"type": "info", "text": "Schedule is well-balanced, but still can be improved"}, + ], "overloaded_users": [user2.public_primary_key], } @@ -89,7 +98,10 @@ def test_get_schedule_score_09_12(get_schedule_quality_response): assert response.json() == { "total_score": 100, - "comments": ["Schedule has no gaps", "Schedule is perfectly balanced"], + "comments": [ + {"type": "info", "text": "Schedule has no gaps"}, + {"type": "info", "text": "Schedule is perfectly balanced"}, + ], "overloaded_users": [], } @@ -100,6 +112,9 @@ def test_get_schedule_score_09_19(get_schedule_quality_response): assert response.json() == { "total_score": 70, - "comments": ["Schedule has gaps", "Schedule is perfectly balanced"], + "comments": [ + {"type": "warning", "text": "Schedule has gaps"}, + {"type": "info", "text": "Schedule is perfectly balanced"}, + ], "overloaded_users": [], }