Документация ЛК
Модули

Статусы

Модуль "Статусы"

Версия: 1.0
Дата: 2025-11-27
Статус: Реализован


Содержание

  1. Общее описание
  2. Текущая реализация
  3. Права доступа
  4. Описание полей
  5. UI/UX
  6. Бизнес-логика
  7. Выявленные проблемы
  8. Рекомендации

1. Общее описание

1.1 Предназначение модуля

Модуль "Статусы" — это ключевой модуль управления жизненным циклом заказов. Он определяет:

  • Какие статусы существуют в системе
  • Разрешённые переходы между статусами
  • Кто может переключать статусы
  • Какие поля обязательны при смене статуса
  • Кого оповещать при смене статуса

Основные функции:

  • Создание и редактирование статусов заказов
  • Настройка переходов между статусами (State Machine)
  • Гибкая система прав на переключение
  • Обязательные поля при переходе
  • Оповещения участников

1.2 Связь с другими модулями

МодульСвязь
Заказыorder.status_id → текущий статус заказа
История заказовФиксация всех переходов
УведомленияОповещения при смене статуса
Все ролиПрава на переключение статусов

1.3 Статистика

МетрикаЗначение
Всего статусов10
Переходов17
Политик статусов9

1.4 Список статусов

IDКлючНазвание
1newНовый
2applyОжидает подписания
3paymentОжидает оплаты
4paidНа проверке
5productionВ производстве
6deliveryДоставка
10pickupОжидает самовывоза
7installМонтаж
8completedЗавершен
9canceledОтменен

2. Текущая реализация

2.1 Архитектура

┌─────────────────────────────────────────────────────────────────────────────┐
│                            МОДУЛЬ "СТАТУСЫ"                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  РОУТЫ (routes/web.php)                                                      │
│  ├── GET /statuses         → StatusController@index  → Список                │
│  ├── GET /status/add       → StatusController@create → Создание              │
│  └── GET /status/edit/{id} → StatusController@show   → Редактирование        │
│                                                                              │
│  КОНТРОЛЛЕР (StatusController.php)                                           │
│  └── Проверка прав: status_can_view                                          │
│                                                                              │
│  LIVEWIRE КОМПОНЕНТЫ                                                         │
│  ├── Status/Listing.php  — Таблица статусов с drag&drop                     │
│  ├── Status/Add.php      — Форма создания                                   │
│  ├── Status/Edit.php     — Форма с 4 вкладками                              │
│  └── Status/Policies.php — Политики статуса                                 │
│                                                                              │
│  МОДЕЛИ                                                                      │
│  ├── Status           — Статус заказа                                       │
│  ├── StatusTransition — Переход между статусами                             │
│  ├── StatusPolicy     — Типы политик статусов                               │
│  └── PolicyStatus     — Значения политик для статуса                        │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

2.2 Структура БД

Таблица statuses

ПолеТипОписание
idbigintPK
indexintПорядок сортировки
status_keystringУникальный ключ (new, paid, etc.)
namestringНазвание для отображения
colorstringЦвет статуса (hex)
descriptionstringОписание
notify_managerbooleanОповещать менеджера
notify_adminbooleanОповещать админов
notify_dealerbooleanОповещать дилера
notify_makebooleanОповещать производство
created_attimestamp
updated_attimestamp

Таблица status_transitions

ПолеТипОписание
idbigintPK
parent_status_idFKИсходный статус
child_status_idFKЦелевой статус
dealer_canbooleanДилер заказа может
manager_canbooleanМенеджер заказа может
production_canbooleanПроизводство заказа может
dealers_canbooleanВсе дилеры могут
managers_canbooleanВсе менеджеры могут
productions_canbooleanВсё производство может
required_fieldsjsonОбязательные поля
forced_fieldsjsonПринудительные поля

Таблица status_policies

ПолеТипОписание
idbigintPK
keystringКлюч политики
namestringНазвание

Таблица policy_status

ПолеТипОписание
idbigintPK
status_idFKСтатус
status_policy_idFKПолитика
valuebooleanЗначение

2.3 Файлы модуля

app/
├── Http/Controllers/
│   └── StatusController.php
├── Livewire/Status/
│   ├── Add.php       — Форма создания
│   ├── Edit.php      — Форма редактирования (4 вкладки)
│   ├── Listing.php   — Таблица списка
│   └── Policies.php  — Политики статуса
└── Models/
    ├── Status.php
    ├── StatusTransition.php
    ├── StatusPolicy.php
    └── PolicyStatus.php

database/migrations/
├── 2024_03_22_143058_create_statuses_table.php
├── 2024_03_30_123459_create_status_transitions_table.php
├── 2024_03_31_170227_create_status_policies_table.php
├── 2024_03_31_170848_create_policy_status_table.php
├── 2025_07_14_170317_add_field_notify_to_statuses_table.php
└── 2025_07_14_184808_add_field_forced_fields_to_status_transitions_table.php

3. Права доступа

3.1 Политика модуля

ПолитикаОписание
status_can_viewПросмотр, создание и редактирование статусов

⚠️ Одна политика для всех действий! Нет отдельных прав на создание/редактирование/удаление.

3.2 Проверка в контроллере

// StatusController.php — везде одна и та же проверка
if (!$user->check_access('status_can_view'))
    abort(403);

3.3 Матрица доступа

РольПросмотрСозданиеРедактир.Удаление
Администратор✅*✅*✅*✅*
Менеджер
Производство
Дилер

*Зависит от политики status_can_view


4. Описание полей

4.1 Форма создания (Add.php)

ПолеТипОбязательноеОписание
status_keyTextInputУникальный ключ
nameTextInputНазвание
colorColorPickerЦвет статуса
descriptionTextInputОписание

4.2 Форма редактирования (Edit.php) — 4 вкладки

Вкладка "Данные"

ПолеТипОписание
status_keyTextInputКлюч (unique)
nameTextInputНазвание
colorColorPickerЦвет
descriptionTextInputОписание

Вкладка "Оповещения"

ПолеТипОписание
notify_managerToggleОповещать менеджера
notify_adminToggleОповещать админов
notify_dealerToggleОповещать дилера
notify_makeToggleОповещать производство

Вкладка "Переходы"

Repeater со следующими полями:

ПолеТипОписание
child_status_idSelectЦелевой статус
required_fieldsSelect (multiple)Обязательные поля
forced_fieldsSelect (multiple)Принудительные поля
dealer_canToggleДилер заказа может
manager_canToggleМенеджер заказа может
production_canToggleПроизводство заказа может
dealers_canToggleВсе дилеры могут
managers_canToggleВсе менеджеры могут
productions_canToggleВсё производство может

Доступные обязательные поля:

КлючНазвание
snСерийный номер
specificationСпецификация
payment_orderПодтверждение оплаты
invoiceСчет
date_makeДата производства
date_deliveryДата доставки
date_paymentДата оплаты
paymentТип оплаты
receiverФИО Клиента
phoneТелефон
emailEmail
deliveryСпособ доставки
addressАдрес

Вкладка "Политики"

Таблица с политиками статуса.

4.3 Колонки таблицы списка

КолонкаОписаниеОсобенности
status_keyКлючПоиск
nameНазваниеПоиск
colorЦветColorColumn

5. UI/UX

5.1 Список статусов

┌─────────────────────────────────────────────────────────────────────────────┐
│ Статусы                                    [Изменить порядок] [+ Создать]   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                    [Поиск...] [Столбцы ▾]   │
├──────────────────┬────────────────────────┬─────────────┬───────────────────┤
│ ☐ Ключ           │ Название               │ Цвет        │                   │
├──────────────────┼────────────────────────┼─────────────┼───────────────────┤
│ ☐ new            │ Новый                  │ ●           │ [Удалить]         │
│ ☐ apply          │ Ожидает подписания     │ ●           │ [Удалить]         │
│ ☐ payment        │ Ожидает оплаты         │ ●           │ [Удалить]         │
│ ☐ paid           │ На проверке            │ ●           │ [Удалить]         │
│ ☐ production     │ В производстве         │ ●           │ [Удалить]         │
│ ☐ delivery       │ Доставка               │ ●           │ [Удалить]         │
│ ☐ pickup         │ Ожидает самовывоза     │ ●           │ [Удалить]         │
│ ☐ install        │ Монтаж                 │ ●           │ [Удалить]         │
│ ☐ completed      │ Завершен               │ ●           │ [Удалить]         │
│ ☐ canceled       │ Отменен                │ ●           │ [Удалить]         │
└──────────────────┴────────────────────────┴─────────────┴───────────────────┘

Особенности:
✅ Drag & Drop для изменения порядка (reorderable)
✅ Кнопка "Изменить порядок" для активации режима
✅ Массовое удаление

5.2 Карточка редактирования (4 вкладки)

┌─────────────────────────────────────────────────────────────────────────────┐
│ [← Назад]  Редактирование статуса              [Удалить]     [Сохранить]    │
├─────────────────────────────────────────────────────────────────────────────┤
│  [Данные]  [Оповещения]  [Переходы]  [Политики]                             │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   Ключ*                           Название*                                 │
│   [new                        ]   [Новый                            ]       │
│                                                                              │
│   Цвет                            Описание                                  │
│   [#070807              ] ●       [                                 ]       │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

6. Бизнес-логика

6.1 State Machine (Машина состояний)

Система статусов реализует State Machine для заказов:

                    ┌─────────────┐
                    │    new      │ (Новый)
                    └──────┬──────┘

                    ┌──────▼──────┐
                    │   apply     │ (Ожидает подписания)
                    └──────┬──────┘

                    ┌──────▼──────┐
                    │  payment    │ (Ожидает оплаты)
                    └──────┬──────┘

                    ┌──────▼──────┐
                    │    paid     │ (На проверке)
                    └──────┬──────┘

                    ┌──────▼──────┐
                    │ production  │ (В производстве)
                    └──────┬──────┘

              ┌────────────┼────────────┐
              │            │            │
       ┌──────▼──────┐     │     ┌──────▼──────┐
       │  delivery   │     │     │   pickup    │
       │ (Доставка)  │     │     │ (Самовывоз) │
       └──────┬──────┘     │     └──────┬──────┘
              │            │            │
              └────────────┼────────────┘

                    ┌──────▼──────┐
                    │  install    │ (Монтаж)
                    └──────┬──────┘

                    ┌──────▼──────┐
                    │  completed  │ (Завершен)
                    └─────────────┘
                           
        ┌─────────────┐
        │  canceled   │ (Отменен) — из любого статуса
        └─────────────┘

6.2 Проверка доступных переходов

// Status.php — availableTransitions()
public function availableTransitions($order, $user): array
{
    $out = [];
    switch ($user->group_id) {
        case '1': // admin — все переходы
            $condition = ['check' => 'all'];
            break;
        case '2': // dealer
            if ($order->dealer_id == $user->id) {
                // Свой заказ — dealer_can OR dealers_can
                $condition = ['check' => 'two', 'first' => 'dealer_can', 'second' => 'dealers_can'];
            } else {
                // Чужой заказ — только dealers_can
                $condition = ['check' => 'one', 'second' => 'dealers_can'];
            }
            break;
        case '3': // manager
            $isOwnOrder = ($order->dealer->company->manager_id == $user->id);
            if ($isOwnOrder) {
                $condition = ['check' => 'two', 'first' => 'manager_can', 'second' => 'managers_can'];
            } else {
                $condition = ['check' => 'one', 'second' => 'managers_can'];
            }
            break;
        case '4': // production
            $condition = ['check' => 'two', 'first' => 'production_can', 'second' => 'productions_can'];
            break;
    }
    // Фильтрация переходов по условиям...
}

6.3 Права на переходы

ФлагКто можетОписание
dealer_canДилер заказаТолько если это его заказ
manager_canМенеджер заказаТолько если это его компания
production_canПроизводство заказаТолько если это их производство
dealers_canВсе дилерыЛюбой дилер
managers_canВсе менеджерыЛюбой менеджер
productions_canВсё производствоЛюбой производственник

6.4 Обязательные поля при переходе

При смене статуса система проверяет required_fields:

// Пример: переход в статус "production" требует:
'required_fields' => ['date_make', 'sn']

Если поля не заполнены — переход заблокирован.

6.5 Принудительные поля

forced_fields — поля, которые система устанавливает автоматически:

'forced_fields' => ['deferred_payment']  // Отсрочка платежа

6.6 Оповещения

При смене статуса система проверяет флаги оповещений:

if ($status->notify_manager) // Отправить уведомление менеджеру
if ($status->notify_admin)   // Отправить уведомление админам
if ($status->notify_dealer)  // Отправить уведомление дилеру
if ($status->notify_make)    // Отправить уведомление производству

7. Выявленные проблемы

7.1 Критические

#ПроблемаФайлВлияние
Критических проблем не обнаружено

7.2 Средние

#ПроблемаОписаниеРешение
1Одна политика на всёstatus_can_view для просмотра, создания и редактированияРазделить на status_can_add, status_can_edit, status_can_delete
2Нет проверки прав в ListingДействие удаления доступно всем, кто видит страницуДобавить проверку прав
3Нет валидации целостностиМожно удалить статус, который используется в заказахДобавить soft delete или проверку

7.3 Низкие

#ПроблемаОписание
4Redirect по status_keyПосле создания редирект на /status/edit/{status_key}, а не на ID
5Нет визуализации графа переходовСложно понять структуру переходов
6Нет истории измененийНе видно, кто и когда менял настройки статуса

8. Рекомендации

8.1 Приоритет: Высокий

Разделить политики

// Создать отдельные политики:
'status_can_view' просмотр списка
'status_can_add' создание
'status_can_edit' редактирование
'status_can_delete' удаление

Добавить защиту от удаления используемых статусов

// В Listing.php
Action::make('delete')
    ->hidden(fn (Status $record) => Order::where('status_id', $record->id)->exists())
    ->requiresConfirmation()
    ->action(fn (Status $record) => $record->delete())

8.2 Приоритет: Средний

Добавить визуализацию графа переходов

Использовать библиотеку типа Mermaid.js для отображения State Machine.

8.3 Приоритет: Низкий

Унифицировать redirect

// Add.php:52 — было:
redirect()->route('status-edit', $record->status_key);

// Стало:
redirect()->route('status-edit', $record->id);

Приложение: SQL для аналитики

Все переходы с правами

SELECT 
    ps.name as from_status,
    cs.name as to_status,
    st.dealer_can,
    st.manager_can,
    st.production_can,
    st.dealers_can,
    st.managers_can,
    st.productions_can,
    st.required_fields
FROM status_transitions st
JOIN statuses ps ON st.parent_status_id = ps.id
JOIN statuses cs ON st.child_status_id = cs.id
ORDER BY ps.index, cs.index;

Статусы с количеством заказов

SELECT 
    s.status_key,
    s.name,
    COUNT(o.id) as orders_count
FROM statuses s
LEFT JOIN orders o ON s.id = o.status_id
GROUP BY s.id, s.status_key, s.name
ORDER BY s.index;

Статусы с настройками оповещений

SELECT 
    status_key,
    name,
    notify_manager,
    notify_admin,
    notify_dealer,
    notify_make
FROM statuses
ORDER BY `index`;

Документ подготовлен на основе анализа исходного кода проекта

On this page

Модуль "Статусы"Содержание1. Общее описание1.1 Предназначение модуля1.2 Связь с другими модулями1.3 Статистика1.4 Список статусов2. Текущая реализация2.1 Архитектура2.2 Структура БДТаблица statusesТаблица status_transitionsТаблица status_policiesТаблица policy_status2.3 Файлы модуля3. Права доступа3.1 Политика модуля3.2 Проверка в контроллере3.3 Матрица доступа4. Описание полей4.1 Форма создания (Add.php)4.2 Форма редактирования (Edit.php) — 4 вкладкиВкладка "Данные"Вкладка "Оповещения"Вкладка "Переходы"Вкладка "Политики"4.3 Колонки таблицы списка5. UI/UX5.1 Список статусов5.2 Карточка редактирования (4 вкладки)6. Бизнес-логика6.1 State Machine (Машина состояний)6.2 Проверка доступных переходов6.3 Права на переходы6.4 Обязательные поля при переходе6.5 Принудительные поля6.6 Оповещения7. Выявленные проблемы7.1 Критические7.2 Средние7.3 Низкие8. Рекомендации8.1 Приоритет: ВысокийРазделить политикиДобавить защиту от удаления используемых статусов8.2 Приоритет: СреднийДобавить визуализацию графа переходов8.3 Приоритет: НизкийУнифицировать redirectПриложение: SQL для аналитикиВсе переходы с правамиСтатусы с количеством заказовСтатусы с настройками оповещений