54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
# -*- 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)
|