# -*- coding: utf-8 -*- # hub/ticket/domain/ticket_transition_policy.py """Политика допусков переходов между состояниями Ticket.""" from __future__ import annotations from dataclasses import dataclass from .task import TicketTask from .ticket_constants import ( STATE_COMPLETED, STATE_CONFIRMATION, STATE_IN_PROGRESS, STATE_TODO, ) @dataclass(frozen=True, slots=True) class TransitionDecision: """Результат проверки допуска перехода.""" allowed: bool reason: str = "" class TicketTransitionPolicy: """Доменные проверки допуска переходов Ticket.""" def can_advance(self, task: TicketTask) -> TransitionDecision: """Проверить возможность перехода в следующее состояние.""" if task.state_code == STATE_TODO and not task.assigned_specialist.strip(): return TransitionDecision( allowed=False, reason="Без назначенного специалиста нельзя перейти в 'В работе'.", ) if task.state_code == STATE_IN_PROGRESS: if not task.diagnostic_report_signed or not task.repair_report_signed: return TransitionDecision( allowed=False, reason="Без двух подписанных отчётов нельзя перейти в 'Подтверждение'.", ) if task.state_code == STATE_CONFIRMATION and not task.acceptance_report_signed: return TransitionDecision( allowed=False, reason="Без акта приёмки нельзя перейти в 'Выполненные'.", ) if task.state_code == STATE_COMPLETED: return TransitionDecision( allowed=False, reason="Выполненная задача не должна принимать лишние сигналы до архивации.", ) return TransitionDecision(allowed=True)