from typing import List, Tuple, cast from redminelib.resources import Issue from .types import ReportRow from .utils import get_version, hours_to_human STATUS_TRANSLATION = { "New": "В работе", "In Progress": "В работе", "Feedback": "В работе", "Re-opened": "В работе", "Code Review": "Решена", "Wait Release": "Закрыто", "Pending": "Ожидание", "Resolved": "Решена", "Testing": "Решена", "Confirming": "Ожидание", "Closed": "Закрыто", "Rejected": "Закрыто", "Frozen": "Ожидание", } def build_grouped_report( issue_hours: List[Tuple[Issue, float]], fill_time: bool = True, ) -> List[ReportRow]: """ Преобразует список задач с затраченным временем в плоский список строк отчёта, с учётом группировки по проекту и версии (пустые ячейки для повторяющихся значений). """ rows: List[ReportRow] = [] prev_project: str = "" prev_version: str = "" for issue, hours in issue_hours: project = str(issue.project) version = get_version(issue) status_en = str(issue.status) status_ru = STATUS_TRANSLATION.get(status_en, status_en) time_text = hours_to_human(hours) if fill_time else "" display_project = project if project != prev_project else "" display_version = version if (project != prev_project or version != prev_version) else "" rows.append( cast( ReportRow, { "project": project, "version": version, "display_project": display_project, "display_version": display_version, "issue_id": issue.id, "subject": issue.subject, "status_ru": status_ru, "time_text": time_text, }, ) ) prev_project = project prev_version = version return rows