Заказы
Полная документация по работе с заказами
Полная документация по работе с заказами
Версия: 2.0
Дата: декабрь 2025
Протестировано: 4 декабря 2025
Содержание
- Список заказов
- Карточка заказа
- Статусы и переходы
- Права доступа по ролям
- Бизнес-логика
- Вкладки карточки
- Уведомления
- Ограничения и особенности
1. Список заказов
URL: /orders
1.1 Элементы интерфейса
| Элемент | Описание |
|---|---|
| Кнопка "Создать" | Создание нового заказа (/order/add) |
| Кнопка "Экспорт" | Экспорт списка заказов в файл |
| Фильтр "Дилер" | Выбор дилера для фильтрации |
| Фильтр "Статус" | Фильтрация по статусу заказа |
| Фильтр "Создан с/по" | Фильтрация по дате создания |
| Поиск | Полнотекстовый поиск по заказам |
| Пагинация | 5/10/25/50/Все записей на странице |
1.2 Колонки таблицы
| Колонка | Описание | Сортировка |
|---|---|---|
| Номер | Формат YYYY_MM_N | ✅ |
| Товар | Название основного товара | ❌ |
| Дилер | ФИО дилера (сокращённо) | ✅ |
| Дата производства | Плановая дата изготовления | ✅ |
| Сумма | Итоговая стоимость в рублях | ✅ |
| Статус | Текущий статус заказа | ✅ |
| Действия | Скачать бланк, Удалить | ❌ |
1.3 Действия в списке
| Действие | Доступность |
|---|---|
| Скачать бланк | Для всех заказов |
| Удалить | По правам роли и статуса |
2. Карточка заказа
URL: /order/edit/{id}
Карточка заказа содержит всю информацию о заказе с возможностью редактирования в зависимости от роли пользователя и статуса заказа.
Структура интерфейса
1. Заголовок
┌─────────────────────────────────────────────────────────────────┐
│ Заказ №2025_10_14 на сумму 204 700 руб ОАО БухТех │
│ (ссылка на дилера)│
└─────────────────────────────────────────────────────────────────┘Элементы:
- Номер заказа — формат
YYYY_MM_DDили порядковый номер - Сумма — итоговая стоимость заказа в рублях
- Компания дилера — кликабельная ссылка на карточку дилера (скрыта для дилеров)
2. Статусы заказа
[Новый] [Ожидает подписания] [Ожидает оплаты] [На проверке] [В производстве] ...Все статусы системы:
| Статус | Описание |
|---|---|
| Новый | Заказ только создан |
| Ожидает подписания | Ожидается подпись спецификации |
| Ожидает оплаты | Ожидается оплата заказа |
| На проверке | Заказ на проверке у руководства |
| В производстве | Станция изготавливается |
| Доставка | Заказ в процессе доставки |
| Ожидает самовывоза | Готов к самовывозу |
| Монтаж | Монтаж на объекте |
| Завершен | Заказ выполнен |
| Отменен | Заказ отменен |
Логика переходов:
- Активные кнопки — доступные переходы для текущего пользователя
- Disabled кнопки — недоступные переходы
- Переходы зависят от роли и матрицы в
/statuses
3. Вкладки
Карточка содержит 3 вкладки:
| Вкладка | Содержание |
|---|---|
| Общая информация | Все поля заказа, файлы, чаты |
| Состав | Позиции заказа, опции, цены |
| История | Лог всех изменений заказа |
Вкладка "Общая информация"
Левая часть — Основные поля
Блок дат и номеров
| Поле | Описание | Редактируемость |
|---|---|---|
| Предполагаемая дата | Желаемая дата готовности | Менеджер, Админ |
| Номер спецификации | Номер для документов | Менеджер, Админ (скрыто для дилера) |
| Номер | Автоматический номер заказа | Только чтение |
| Дата изготовления | Фактическая дата производства | Менеджер, Админ |
| Дата доставки | Дата доставки клиенту | Менеджер, Админ |
| Заказ создан | Дата/время создания | Только чтение |
| Дата оплаты | Дата получения оплаты | Все (кроме disabled) |
Блок оплаты и доставки
| Поле | Описание | Варианты |
|---|---|---|
| Отсрочка платежа | Флаг отсрочки | Вкл/Выкл (скрыто для дилера) |
| Форма оплаты | Способ оплаты | Безналичный по счету, Безналичный по ссылке, Наличными (бригадиру), Наличными (перевод) |
| Способ доставки | Тип получения | Самовывоз, Доставка по адресу |
| Склад | Склад отгрузки | Вертек, Склад СПБ, Базис |
| Производство | Место изготовления | Производство Верховье, Производство Елкино (только чтение) |
| Адрес изготовления | Адрес производства | Текстовое поле |
Блок "Данные заказа"
| Поле | Описание |
|---|---|
| ФИО клиента | Полное имя конечного покупателя |
| Телефон | Контактный телефон клиента |
| Электронная почта клиента | |
| Адрес | Адрес доставки или монтажа |
| Нужен монтаж | Флаг необходимости монтажа |
| Комментарий к заказу | Произвольный комментарий |
Блок "Контактное лицо на объекте"
| Поле | Описание |
|---|---|
| ФИО | Имя лица, принимающего товар |
| Телефон | Телефон контактного лица |
Блок "Файлы"
| Поле | Кто видит | Кто редактирует |
|---|---|---|
| Файлы | Все | По правам |
| Документы от менеджера | Менеджер, Админ | Менеджер, Админ |
| Документы от дилера | Все | Дилер |
Правая часть — Документы и чаты
Генерация документов
| Кнопка | Описание | Доступность |
|---|---|---|
| Бланк | Скачать бланк заказа (Excel) | Менеджер, Админ |
| Спецификация | Скачать спецификацию (Excel) | Все |
Требования для генерации спецификации:
- Заполнена компания дилера
- Указан склад и его адрес
- Указан способ доставки
- Заполнен заказчик (ФИО)
- Указан телефон
Прикрепление документов
| Поле | Описание | Редактор |
|---|---|---|
| Спецификация | Подписанная спецификация | Менеджер |
| Счет | Счет на оплату | Менеджер |
| Подтверждение оплаты | Платежное поручение | Все |
| Доверенность на получение | Доверенность | Все |
Чаты
| Чат | Участники |
|---|---|
| Внутренний чат | Менеджеры, Админы (дилер не видит) |
| Чат с дилером | Все участники |
Вкладка "Состав"
Управление позициями заказа.
Режимы отображения:
- Основные товары — станции, кессоны и т.д.
- Дополнительные товары — компрессоры, насосы и т.д.
Функции для каждой позиции:
| Действие | Описание |
|---|---|
| +/- Количество | Изменить количество единиц товара |
| +/- Высота горловины | Наращивание (шаг 100мм, макс 500мм) |
| Опции входов | Торцевой, Левый, Правый (110мм) |
| Одиночные опции | Дополнительное оборудование |
| Индивидуальная скидка | Процент скидки на позицию (0-100%) |
| Серийный номер | SN станции (для производства) |
Расчет цен:
Стоимость позиции = (Цена × Количество) + Наращивание + Опции
Итого дилеру = Сумма всех позиций с дилерской скидкой
Итого клиенту = Сумма всех позиций по розничной ценеВкладка "История"
Таблица всех изменений заказа.
| Колонка | Описание |
|---|---|
| Дата и время | Когда произошло изменение |
| Пользователь | Кто сделал изменение |
| Статус | Новый статус заказа |
| Действие | Описание действия |
Фиксируются:
- Смена статуса заказа
- Изменения полей (если реализовано)
- Загрузка файлов
3. Статусы и переходы
3.1 Все статусы системы
| ID | Ключ | Название | Порядок |
|---|---|---|---|
| 1 | new | Новый | 1 |
| 2 | apply | Ожидает подписания | 2 |
| 3 | payment | Ожидает оплаты | 3 |
| 4 | paid | На проверке | 4 |
| 5 | production | В производстве | 5 |
| 6 | delivery | Доставка | 6 |
| 10 | pickup | Ожидает самовывоза | 7 |
| 7 | install | Монтаж | 8 |
| 8 | completed | Завершен | 9 |
| 9 | canceled | Отменен | 10 |
3.2 Матрица переходов между статусами
Новый ──────────────────► Ожидает подписания [менеджер]
│
▼
Ожидает оплаты [менеджер]
│
▼
На проверке [менеджер]
│
▼
В производстве [производство]
/ │ \
▼ ▼ ▼
Ожидает самовывоза Доставка Монтаж [производство]
│ │ │
└───────────────┼──────────┘
▼
Завершен [менеджер/производство]3.3 Подробные переходы
| Из статуса | В статус | Кто может |
|---|---|---|
| Новый | Ожидает подписания | Менеджер |
| Ожидает подписания | Ожидает оплаты | Менеджер |
| Ожидает подписания | Новый | Менеджер (откат) |
| Ожидает оплаты | На проверке | Менеджер |
| Ожидает оплаты | Ожидает подписания | Менеджер (откат) |
| На проверке | В производстве | Производство |
| На проверке | На проверке | Менеджер (пересмотр) |
| В производстве | Доставка | Производство |
| В производстве | Ожидает самовывоза | Производство |
| В производстве | Монтаж | Производство |
| В производстве | На проверке | Производство (откат) |
| Доставка | Ожидает самовывоза | Производство |
| Доставка | Монтаж | Производство |
| Доставка | Завершен | Менеджер, Производство |
| Ожидает самовывоза | Монтаж | Менеджер, Производство |
| Ожидает самовывоза | Завершен | Менеджер, Производство |
| Монтаж | Завершен | Менеджер |
4. Права доступа по ролям
4.1 Матрица прав по статусам
| Статус | Менеджер | Дилер | Производство |
|---|---|---|---|
| Новый | 👁️✏️🗑️ | 👁️✏️ | 👁️ |
| Ожидает подписания | 👁️✏️ | 👁️✏️ | ❌ |
| Ожидает оплаты | 👁️✏️ | 👁️ | 👁️ |
| На проверке | 👁️🗑️ | 👁️ | 👁️✏️ |
| В производстве | 👁️ | 👁️ | 👁️✏️ |
| Доставка | 👁️ | 👁️ | 👁️✏️ |
| Ожидает самовывоза | 👁️✏️ | 👁️ | 👁️ |
| Монтаж | 👁️ | 👁️ | 👁️ |
| Завершен | 👁️ | 👁️ | 👁️ |
| Отменен | 👁️✏️ | ❌ | 👁️ |
Легенда: 👁️ просмотр, ✏️ редактирование, 🗑️ удаление
4.2 Администратор (group_id = 1)
- ✅ Полный доступ ко всем заказам и полям
- ✅ Любые переходы между статусами
- ✅ Генерация всех документов
- ✅ Просмотр внутреннего чата
- ✅ Просмотр удалённых заказов (SoftDeletes)
- ✅ Impersonation (авторизация под другим пользователем)
4.3 Менеджер (group_id = 3)
- ✅ Просмотр/редактирование заказов своих дилеров (привязка через company_id)
- ✅ Переходы: Новый → Ожидает подписания → Ожидает оплаты → На проверке
- ✅ Завершение заказов из статусов Доставка/Самовывоз
- ✅ Генерация документов (Бланк, Спецификация)
- ✅ Внутренний чат + чат с дилером
- ❌ Заказы чужих дилеров
4.4 Дилер (group_id = 2)
- ✅ Просмотр только своих заказов
- ✅ Редактирование в статусах: Новый, Ожидает подписания
- ✅ Загрузка файлов: Подтверждение оплаты, Доверенность, Документы от дилера
- ✅ Чат с менеджером
- ❌ Внутренний чат (не видит)
- ❌ Поле "Номер спецификации"
- ❌ Поле "Отсрочка платежа"
- ❌ Кнопка "Бланк"
- ❌ Заказы в статусе "Отменен"
4.5 Производство (group_id = 4)
- ✅ Просмотр заказов в статусах: Новый, Ожидает оплаты, На проверке, В производстве, Доставка, Завершен, Отменен
- ✅ Редактирование в статусах: На проверке, В производстве, Доставка
- ✅ Переходы: На проверке → В производстве → Доставка/Самовывоз/Монтаж → Завершен
- ✅ Добавление серийного номера
- ❌ Чат с дилером
- ❌ Изменение конфигурации товара
Пошаговая работа с заказом
Сценарий: Обработка нового заказа (Менеджер)
- Открыть заказ из списка
/orders - Проверить данные на вкладке "Общая информация"
- Скачать спецификацию → кнопка "Спецификация"
- Отправить дилеру на подпись
- Получить подписанную → загрузить в "Спецификация"
- Сменить статус → "Ожидает подписания"
- Получить оплату → загрузить в "Подтверждение оплаты"
- Сменить статус → "Ожидает оплаты" → "На проверке"
- Передать в производство → "В производстве"
Сценарий: Добавление серийного номера (Производство)
- Открыть заказ в статусе "В производстве"
- Перейти на вкладку "Состав"
- Нажать на поле SN у позиции
- Ввести серийный номер
- Сохранить
- Сменить статус → "Доставка" или "Ожидает самовывоза"
Автосохранение
Все изменения полей сохраняются автоматически при:
- Потере фокуса поля (
onBlur) - Изменении toggle-переключателей (
live)
Статус изменяется сразу при клике на кнопку статуса с перезагрузкой страницы.
5. Бизнес-логика
5.1 Создание заказа
При создании заказа автоматически:
- Генерируется номер в формате
YYYY_MM_N(год_месяц_порядковый номер) - Генерируется номер спецификации на основе компании дилера:
- Берётся
specification_start_numberиз компании - Прибавляется количество существующих заказов компании
- Берётся
5.2 Система скидок дилера
Источник скидок
Скидки хранятся в таблице category_company:
| Поле | Описание |
|---|---|
category_id | ID категории верхнего уровня |
company_id | ID компании дилера |
discount | Процент скидки (0-100) |
Пример скидок для компании:
ТВЕРЬ LITE → 25%
ТВЕРЬ CLASSIC → 30%
ТВЕРЬ AERO → 35%
КЕССОНЫ → 20%
ПОГРЕБА → 20%
ТВЕРЬ PRO → 35%Применение скидки
// Метод calculateDealerPrice() в Compound.php:
// 1. Для ОСНОВНЫХ товаров — скидка компании по категории:
$category = $product->categories->first()->getTopLevelParent();
$discount = $dealer->discount($category->id); // из category_company
$priceDealer = $price * (1 - $discount / 100);
// 2. Для ДОПОЛНИТЕЛЬНЫХ товаров — фиксированная дилерская цена:
$priceDealer = $product->dealer_price; // из справочника productsИндивидуальная скидка
Дополнительная скидка на конкретную позицию заказа (0-100%):
// Применяется ПОСЛЕ скидки компании:
$finalPrice = $priceDealer * (1 - $individualDiscount / 100);Доступность: только для Менеджера и Администратора (дилер не видит поле).
5.3 Расчёт стоимости
Стоимость позиции = (Цена товара × Количество) + Наращивание + Опции
Дилерская цена = Розничная цена × (1 - Скидка компании) × (1 - Инд. скидка)
Итого заказа = Сумма всех позиций + Дополнительные товарыНаращивание горловины:
- Шаг: 100мм
- Максимум: 500мм (50см)
- Цена за шаг: указана в товаре (
step_price,step_price_dealer)
Опции входов:
- Первый вход — бесплатно
- Каждый последующий — по цене опции
- Типы: Торцевой, Левый, Правый (110мм)
5.4 Удаление заказа
При удалении заказа:
- Статус меняется на
canceled - Срабатывает SoftDelete (запись не удаляется физически)
- Товары со склада освобождаются (
in_stock = true) - Pivot-связи с ProductStock отвязываются
5.5 Отмена заказа
При переходе в статус canceled:
- Вызывается метод
releaseStocks() - Все привязанные товары со склада возвращаются в наличие
- Серийные номера обнуляются
6. Вкладки карточки (детально)
6.1 Вкладка "Общая информация"
Левая колонка — основные поля:
| Поле | Тип | Описание | Редактируемость |
|---|---|---|---|
| Предполагаемая дата | text | Желаемая дата готовности | Менеджер, Админ |
| Номер спецификации | number | Номер для документов | Менеджер, Админ (скрыто для дилера) |
| Номер | text | Автоматический номер заказа | Только чтение |
| Дата изготовления | datetime | Фактическая дата производства | Менеджер, Админ |
| Дата доставки | datetime | Дата доставки клиенту | Менеджер, Админ |
| Заказ создан | datetime | Дата/время создания | Только чтение |
| Дата оплаты | datetime | Дата получения оплаты | По правам |
| Отсрочка платежа | toggle | Флаг отсрочки | Менеджер, Админ (скрыто для дилера) |
| Форма оплаты | select | Способ оплаты | По правам |
| Способ доставки | select | Самовывоз / Доставка | По правам |
| Склад | select | Склад отгрузки | По правам |
| Производство | select | Место изготовления | Только чтение |
| Адрес изготовления | text | Адрес производства | По правам |
Блок "Данные заказа":
| Поле | Обязательное | Описание |
|---|---|---|
| ФИО клиента | ✅ для спецификации | Полное имя покупателя |
| Телефон | ✅ для спецификации | Контактный телефон |
| ❌ | Электронная почта | |
| Адрес | ✅ при доставке | Адрес доставки/монтажа |
| Нужен монтаж | ❌ | Флаг необходимости монтажа |
| Комментарий | ❌ | Произвольный комментарий |
Правая колонка:
- Генерация документов: Бланк (Excel), Спецификация (Excel)
- Прикрепление: Спецификация, Счёт, Подтверждение оплаты, Доверенность
- Чаты: Внутренний (без дилера), С дилером
6.2 Вкладка "Состав" — Подвкладка "Основные товары"
Компонент: App\Livewire\Order\Compound (режим mode = 'main')
Blade: resources/views/livewire/order/compound.blade.php
Источники данных
| Данные | Таблица/Модель | Связь |
|---|---|---|
| Позиции заказа | order_items / OrderItem | order_id, is_main = true |
| Опции позиций | order_item_options / OrderItemOption | order_item_id |
| Справочник опций | options / Option | product_id |
| Товары | products / Product | product_id |
Структура позиции основного товара
┌─────────────────────────────────────────────────────────────────┐
│ [Фото] Тверь CLASSIC 0,8НПН Серийный №: — │
│ Септик [Прикрепить серийный номер] │
├─────────────────────────────────────────────────────────────────┤
│ Количество Стоимость позиции Инд. скидка, % Высота │
│ [-] 1 [+] 189 300 руб. [__0___] [-] 0 М [+] │
├─────────────────────────────────────────────────────────────────┤
│ Итого по товару: 190 800 руб. │
├─────────────────────────────────────────────────────────────────┤
│ ┌─ Входы ─────────────────────────────────────────────────────┐ │
│ │ [✓] Вход торцевой ДУ 110 (+1 500 р.) │ │
│ │ [✓] Вход слева ДУ 110 (+1 500 р.) │ │
│ │ [ ] Вход справа ДУ 110 (+1 500 р.) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─ Опции ─────────────────────────────────────────────────────┐ │
│ │ [ ] Дополнительный самотечный выход ДУ 110 (+1 500 р.) │ │
│ │ [ ] Дополнительный самотечный ввод левый (+1 500 р.) │ │
│ │ [ ] Дополнительный самотечный ввод правый (+1 500 р.) │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘Кнопки и действия
| Кнопка | Метод | Описание | Влияние на систему |
|---|---|---|---|
| + Добавить основной товар | addMainProductAction() | Открывает модальное окно выбора товара | Создаёт запись в order_items с is_main=true + копирует опции из options в order_item_options |
| [-] Количество | minusMainItem($id) | Уменьшает количество на 1 (минимум 1) | Обновляет count в order_items, пересчитывает cost |
| [+] Количество | plusMainItem($id) | Увеличивает количество на 1 | Обновляет count, пересчитывает стоимость |
| [-] Высота горловины | stepMinusItem($id) | Уменьшает высоту на шаг (100мм) | Обновляет step_size, пересчитывает step_price |
| [+] Высота горловины | stepPlusItem($id) | Увеличивает высоту на шаг (макс 500мм) | Обновляет step_size, step_price, step_price_dealer |
| Инд. скидка | updateItemDiscount($id, $val) | Устанавливает индивидуальную скидку 0-100% | Обновляет individual_discount, пересчитывает price_dealer |
| Toggle входов | itemGetEntersToggles() | Включает/выключает вход | Обновляет value в order_item_options, первый вход бесплатный |
| Toggle опций | itemGetSinglesToggles() | Включает/выключает опцию | Обновляет value, добавляет цену к price_options |
| Прикрепить SN | openSnModal($id) | Открывает модальное окно ввода SN | Сохраняет sn в order_items |
Логика расчёта цен
// Для каждой позиции (recalculateItem):
$price = $product->price; // Розничная цена товара
$priceDealer = calculateDealerPrice($product, $indDisc); // С учётом скидок
// Наращивание (если step_size > 0):
$stepPrice = $product->step_price * ($item->step_size / $product->step_size);
$stepPriceDealer = $product->step_price_dealer * ($item->step_size / $product->step_size);
// Опции:
// - Входы (enter): первый бесплатный, последующие платные
// - Одиночные (single): все платные
$priceOptions = calculateItemOptionsPrice($item) * $count;
// Итого позиции:
$cost = ($price * $count) + $stepPrice + $priceOptions;
$costDealer = ($priceDealer * $count) + $stepPriceDealer + $priceOptions;Откуда берутся опции (входы и одиночные)
-
Справочник опций — таблица
options:product_id— привязка к товаруgroup— тип:enter(входы) илиsingle(одиночные)type— подтип входа:end(торцевой),left(слева),right(справа)name— название опцииprice— цена опции
-
При добавлении товара в заказ (метод
addMainProductAction):foreach ($product->options as $opt) { OrderItemOption::create([ 'order_item_id' => $item->id, 'option_id' => $opt->id, 'group' => $opt->group, 'type' => $opt->type, 'value' => false, // изначально выключено 'price' => $opt->price, ]); } -
Отображение опций — из
order_item_optionsчерез связь$item->options
Правила входов
| Правило | Описание |
|---|---|
| Первый вход бесплатный | При расчёте calculateItemOptionsPrice() первый включённый вход не учитывается |
| Нельзя снять последний | Если выбран только 1 вход — его нельзя отключить |
| Множественный выбор | Можно выбрать любую комбинацию входов |
Поддержание актуальности данных
-
Изменение справочника опций (
options):- Новые опции появятся только для новых заказов
- Существующие заказы хранят копии опций в
order_item_options
-
Изменение цен товаров (
products.price):- Влияет только на новые заказы
- Существующие позиции хранят цену на момент добавления в
order_items.price
-
Пересчёт — вызывается автоматически при любом изменении:
recalculateItem()→recalculateTotals()→$order->update()
6.3 Вкладка "Состав" — Подвкладка "Доп. опции"
Компонент: App\Livewire\Order\Compound (режим mode = 'extras')
Источники данных
| Данные | Таблица/Модель | Связь |
|---|---|---|
| Доп. товары заказа | order_product / OrderProduct | order_id |
| Справочник товаров | products / Product | product_id |
| Категории | categories / Category | additional = true |
Структура интерфейса
┌─────────────────────────────────────────────────────────────────┐
│ [+ Добавить] │
├─────────────────────────────────────────────────────────────────┤
│ [Фото] Насос Belamos DWP 750 [-] 1 [+] 13 900 [Удалить] │
│ (фекальный насос) │
├─────────────────────────────────────────────────────────────────┤
│ Итого: 13 900 руб. │
└─────────────────────────────────────────────────────────────────┘Кнопки и действия
| Кнопка | Метод | Описание | Влияние на систему |
|---|---|---|---|
| + Добавить | addProductAction() | Открывает модальное окно выбора товара | Создаёт запись в order_product + order_items (is_main=false) |
| [-] | minusProduct($id) | Уменьшает количество (минимум 1) | Обновляет count в order_product |
| [+] | plusProduct($id) | Увеличивает количество | Обновляет count, пересчитывает price_products |
| Удалить | deleteProduct($id) | Удаляет товар из заказа | Удаляет запись из order_product |
Откуда берутся дополнительные товары
-
Категория с флагом
additional = true(ID: 55 "Дополнительные товары") -
Метод
getAdditionalCategoriesWithProducts():$categories = Category::where('additional', true)->get(); foreach ($categories as $category) { $products = $products->merge($category->allProducts()); } // Фильтруем только активные (active = 1) -
Типы дополнительных товаров:
- Компрессоры (Hiblow, Secoh)
- Насосы (фекальные, дренажные)
- Комплектующие
Расчёт дилерской цены для доп. товаров
// Для дополнительных товаров используется dealer_price из справочника:
if ($product->isAdditionalProduct()) {
return $product->dealer_price; // готовая дилерская цена
}Различие от основных товаров:
- Основные товары:
dealer_price = price * (1 - скидка_дилера%) - Дополнительные:
dealer_price— фиксированное значение из справочника
Поддержание актуальности
-
Добавление новых доп. товаров:
- Добавить товар в таблицу
products - Привязать к категории с
additional = trueчерезcategory_product - Установить
active = 1 - Заполнить
priceиdealer_price
- Добавить товар в таблицу
-
Изменение цен:
- Существующие записи в
order_productхранят цену на момент добавления - Новые добавления используют актуальные цены из справочника
- Существующие записи в
6.4 Блок "Стоимость" (правая панель)
Компонент: resources/views/components/order/costs.blade.php
Отображается на обеих подвкладках (Основные товары и Доп. опции).
Структура блока
┌─ Стоимость ──────────────────────────────┐
│ Цена 189 300 руб. │
│ Стоимость опций 1 500 руб. │
│ Доп. опции 13 900 руб. │
│ Цена дилерская 132 510 руб. │
├──────────────────────────────────────────┤
│ Итого для дилера 147 910 руб. │
│ Итого для клиента 204 700 руб. │
└──────────────────────────────────────────┘Расшифровка полей
| Поле | Переменная | Формула |
|---|---|---|
| Цена | $price * $count | Сумма розничных цен основных товаров |
| Стоимость монтажа | $price_install | Если install = true |
| Стоимость опций | $price_options | Сумма включённых входов + опций |
| Наращивание (дилер) | $total_step_price_dealer | Сумма step_price_dealer всех позиций |
| Наращивание (клиент) | $total_step_price | Сумма step_price всех позиций |
| Доп. опции | $price_products | Сумма дополнительных товаров |
| Цена дилерская | $price_dealer * $count | Цена с учётом скидки компании |
| Итого для дилера | $cost_dealer | (price_dealer * count) + step_price_dealer + price_options + price_products |
| Итого для клиента | $cost | (price * count) + step_price + price_options + price_products |
6.5 Вкладка "История"
Таблица order_histories через компонент Order/History.php.
| Колонка | Источник |
|---|---|
| Дата и время | created_at |
| Пользователь | user_id → User |
| Статус | status_key |
| Действие | action |
7. Уведомления
7.1 Telegram-уведомления
Настраиваются в таблице statuses для каждого статуса:
| Флаг | Кому отправляется |
|---|---|
notify_manager | Менеджеру компании дилера |
notify_dealer | Дилеру заказа |
notify_admin | Всем администраторам с tg_id |
notify_make | Всем пользователям производства с tg_id |
Формат сообщения:
Заказ - №2025_10_14.
В статусе - В производстве
Ссылка - https://lk.septiki-tver.ru/order/edit/2827.2 Уведомление при загрузке файла дилером
Когда дилер загружает файл (files_dealer, payment_order, letter_attorney):
- Менеджер компании получает Telegram-уведомление
- Текст: "К заказу №... дилер прикрепил файл"
8. Ограничения и особенности
8.1 Технические ограничения
| Ограничение | Значение |
|---|---|
| Максимум наращивания | 500мм (50см) |
| Максимум входов | 3 (торец + лево + право) |
| Индивидуальная скидка | 0-100% |
| Формат номера заказа | YYYY_MM_N |
8.2 Валидация спецификации
Для генерации спецификации обязательны:
- Компания дилера
- Склад и его адрес
- Способ доставки
- ФИО заказчика
- Телефон
- Адрес (если доставка)
8.3 Особенности интерфейса
- Автосохранение — все поля сохраняются при потере фокуса
- Производство disabled — выбирается автоматически по складу
- Статусы как radio — доступные подсвечены, недоступные disabled
- Вкладки Filament — переключение через Alpine.js
- Чаты — real-time через Laravel Reverb/WebSocket
8.4 Известные проблемы
| Проблема | Статус | Описание |
|---|---|---|
| История изменений | ⚠️ | Фиксируются только смены статуса, не все поля |
| Статичность цен | ❌ | Завершённые заказы не хранят снапшот цен |
| Серийные номера | ⚠️ | Нет полной интеграции со складом |
Приложение: SQL-структура ключевых таблиц
Таблица orders
- id, number, specification_number
- product_id, dealer_id, status_key
- manufacture_id, stock_id
- date_make, date_made, date_delivery, date_payment
- receiver, phone, email, address
- payment, delivery, install, deferred_payment
- comment, contact_name, contact_phone, address_make
- price, price_dealer, price_options, price_products, price_install
- cost, cost_dealer, count
- step_size, step_price, step_price_dealer
- sn, product_stock_id
- files, files_dealer, files_manager (JSON)
- specification, invoice, payment_order, letter_attorney
- created_at, updated_at, deleted_atТаблица status_transitions
- id, parent_status_id, child_status_id
- required_fields, forced_fields (JSON)
- dealer_can, dealers_can
- manager_can, managers_can
- production_can, productions_can