# -*- coding: utf-8 -*- # hub/ticket/ui/details/task_details_view_data.py """Форматирование данных для нового dialog-экрана подробностей Ticket.""" from __future__ import annotations from dataclasses import dataclass from domain import TicketTaskSnapshot, parse_location_parts from domain.ticket_constants import STATE_ARCHIVED, STATE_COMPLETED, STATE_REFUSED from ui.task_view_formatters import ( build_specialist_card_info, build_specialist_photo_path, build_stage_icon_path, can_assign_specialist, can_sign_acceptance, can_sign_diagnostic, can_sign_repair, ) @dataclass(frozen=True, slots=True) class TaskStageRowData: """View-data одной строки этапа выполнения заявки.""" key: str text: str icon_path: str emphasized: bool clickable: bool def build_task_summary_rows(task: TicketTaskSnapshot) -> tuple[tuple[str, str], ...]: institution, room, device = parse_location_parts(task.location or "") return ( ("Учреждение", institution or "Локация не указана"), ("Оборудование", device or "Аппарат не указан"), ("Кабинет", room or "Кабинет не указан"), ("Назначение", build_task_status_text(task)), ) def build_task_status_text(task: TicketTaskSnapshot) -> str: specialist_info = build_specialist_card_info(task.assigned_specialist) short_name = specialist_info["short_name"].strip() if not short_name: return "Специалист не назначен" return short_name def build_employee_view_data(task: TicketTaskSnapshot) -> dict[str, str]: specialist_info = build_specialist_card_info(task.assigned_specialist) short_name = specialist_info["short_name"].strip() position = specialist_info["position"].strip() return { "name": short_name or "Специалист не назначен", "position": position if short_name else "Ожидает назначения", "photo_path": build_specialist_photo_path( task.assigned_specialist, task.specialist_photo, ), } def build_task_stage_rows(task: TicketTaskSnapshot) -> tuple[TaskStageRowData, ...]: return ( TaskStageRowData( key="specialist", text="Специалист назначен" if task.assigned_specialist.strip() else "Назначить специалиста", icon_path=build_stage_icon_path("specialist", True), emphasized=bool(task.assigned_specialist.strip()), clickable=can_assign_specialist(task), ), TaskStageRowData( key="diagnostic", text=( "Отчёт диагностики составлен" if task.diagnostic_report_signed else "Составить отчёт диагностики" ), icon_path=build_stage_icon_path("diagnostic", True), emphasized=bool(task.diagnostic_report_signed), clickable=can_sign_diagnostic(task), ), TaskStageRowData( key="repair", text=( "Отчёт по ремонту составлен" if task.repair_report_signed else "Составить отчёт по ремонту" ), icon_path=build_stage_icon_path("repair", True), emphasized=bool(task.repair_report_signed), clickable=can_sign_repair(task), ), TaskStageRowData( key="acceptance", text=( "Акт приёмки работ подписан" if task.acceptance_report_signed else "Составить акт приёмки работ" ), icon_path=build_stage_icon_path("acceptance", True), emphasized=bool(task.acceptance_report_signed), clickable=can_sign_acceptance(task), ), ) def can_refuse_task(task: TicketTaskSnapshot) -> bool: return task.state_code not in {STATE_COMPLETED, STATE_REFUSED, STATE_ARCHIVED} def can_archive_task(task: TicketTaskSnapshot) -> bool: return task.state_code in {STATE_COMPLETED, STATE_REFUSED}