117 lines
4.3 KiB
Python
117 lines
4.3 KiB
Python
# -*- 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}
|