feat(supplier-orders): добавить параметры поставки в таблицу заявок
- Добавлены колонки Объём и Грузовые места между Цена товаров и Статус - Реализованы инпуты для ввода volume и packagesCount в статусе PENDING для роли WHOLESALE - Добавлена мутация UPDATE_SUPPLY_PARAMETERS с проверками безопасности - Скрыта строка Поставщик для роли WHOLESALE (поставщик знает свои данные) - Исправлено выравнивание таблицы при скрытии уровня поставщика - Реорганизованы документы: legacy-rules/, docs/, docs-and-reports/ ВНИМАНИЕ: Компонент multilevel-supplies-table.tsx (1697 строк) нарушает правило модульной архитектуры (>800 строк требует рефакторинга) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
342
docs/business-processes/EXCHANGE_MODULE_RULES.md
Normal file
342
docs/business-processes/EXCHANGE_MODULE_RULES.md
Normal file
@ -0,0 +1,342 @@
|
||||
# ПРАВИЛА ВНЕДРЕНИЯ МОДУЛЯ "БИРЖА" В СИСТЕМУ SFERA
|
||||
|
||||
## 🎯 ОБЗОР ЗАДАЧИ
|
||||
|
||||
**Цель:** Создание нового раздела "Биржа" во всех кабинетах с переносом функционала из раздела "Маркет"
|
||||
|
||||
**Принцип:** Модульная архитектура с безопасным рефакторингом и сохранением совместимости
|
||||
|
||||
## 📋 ДЕТАЛЬНЫЕ ПРАВИЛА РЕАЛИЗАЦИИ
|
||||
|
||||
### 1. СТРУКТУРНАЯ АРХИТЕКТУРА
|
||||
|
||||
#### 1.1 Создание модульной структуры:
|
||||
|
||||
```
|
||||
src/components/exchange/ # Новый модуль Биржи
|
||||
├── exchange-dashboard.tsx # Главная страница Биржи
|
||||
├── tabs/
|
||||
│ ├── investments-tab.tsx # Перенос из market/investments
|
||||
│ └── market-tab.tsx # Перенос из market/market
|
||||
├── hooks/
|
||||
│ ├── useExchangeData.ts # Хуки для данных биржи
|
||||
│ └── useInvestmentOperations.ts # Логика инвестиций
|
||||
├── components/
|
||||
│ ├── ExchangeHeader.tsx # Заголовок раздела
|
||||
│ └── ExchangeStats.tsx # Статистика биржи
|
||||
└── types/
|
||||
└── exchange.types.ts # TypeScript интерфейы
|
||||
```
|
||||
|
||||
#### 1.2 Обновление навигации:
|
||||
|
||||
```typescript
|
||||
// src/components/dashboard/sidebar.tsx
|
||||
const navigationItems = [
|
||||
// ... существующие пункты
|
||||
{
|
||||
name: 'Биржа',
|
||||
href: '/exchange',
|
||||
icon: TrendingUp, // или Zap, или BarChart3
|
||||
position: 'before-settings', // Над разделом настройки
|
||||
},
|
||||
// ... остальные пункты
|
||||
]
|
||||
```
|
||||
|
||||
### 2. БЕЗОПАСНЫЙ ПЕРЕНОС КОМПОНЕНТОВ
|
||||
|
||||
#### 2.1 Сохранение оригиналов:
|
||||
|
||||
```bash
|
||||
# Создаем backup перед переносом
|
||||
cp -r src/components/market/investments-tab.tsx src/components/market/investments-tab.tsx.backup
|
||||
cp -r src/components/market/market-tab.tsx src/components/market/market-tab.tsx.backup
|
||||
```
|
||||
|
||||
#### 2.2 Поэтапный перенос:
|
||||
|
||||
```typescript
|
||||
// Этап 1: Создание алиасов (временно)
|
||||
export { InvestmentsTab as ExchangeInvestmentsTab } from '../market/investments-tab'
|
||||
export { MarketTab as ExchangeMarketTab } from '../market/market-tab'
|
||||
|
||||
// Этап 2: Копирование с адаптацией
|
||||
// Этап 3: Обновление импортов
|
||||
// Этап 4: Удаление дубликатов
|
||||
```
|
||||
|
||||
### 3. МАРШРУТИЗАЦИЯ И URL
|
||||
|
||||
#### 3.1 Новая структура маршрутов:
|
||||
|
||||
```
|
||||
/exchange # Главная страница Биржи
|
||||
├── /exchange/investments # Инвестиции (было /market/investments)
|
||||
└── /exchange/market # Маркет (было /market/market)
|
||||
|
||||
/market # Остается, но без investments и market
|
||||
├── /market/logistics # Остается
|
||||
├── /market/analytics # Остается
|
||||
└── /market/other-tabs # Остальные вкладки остаются
|
||||
```
|
||||
|
||||
#### 3.2 Редиректы для совместимости:
|
||||
|
||||
```typescript
|
||||
// src/middleware.ts или pages/_app.tsx
|
||||
const redirectRules = [
|
||||
{
|
||||
from: '/market/investments',
|
||||
to: '/exchange/investments',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
from: '/market/market',
|
||||
to: '/exchange/market',
|
||||
permanent: true,
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
### 4. УНИВЕРСАЛЬНОСТЬ ДЛЯ ВСЕХ КАБИНЕТОВ
|
||||
|
||||
#### 4.1 Роль-агностический подход:
|
||||
|
||||
```typescript
|
||||
// src/components/exchange/exchange-dashboard.tsx
|
||||
interface ExchangeDashboardProps {
|
||||
userRole: 'SELLER' | 'WHOLESALE' | 'FULFILLMENT' | 'LOGIST'
|
||||
// Компонент адаптируется под роль, но функционал одинаковый
|
||||
}
|
||||
|
||||
const ExchangeDashboard: FC<ExchangeDashboardProps> = ({ userRole }) => {
|
||||
// Одинаковая логика для всех ролей
|
||||
return (
|
||||
<div className="exchange-dashboard">
|
||||
<ExchangeHeader userRole={userRole} />
|
||||
<ExchangeTabs userRole={userRole} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2 Единая конфигурация:
|
||||
|
||||
```typescript
|
||||
// src/config/exchange.config.ts
|
||||
export const EXCHANGE_CONFIG = {
|
||||
tabs: [
|
||||
{
|
||||
id: 'investments',
|
||||
name: 'Инвестиции',
|
||||
path: '/exchange/investments',
|
||||
availableFor: ['SELLER', 'WHOLESALE', 'FULFILLMENT', 'LOGIST'], // Все роли
|
||||
},
|
||||
{
|
||||
id: 'market',
|
||||
name: 'Маркет',
|
||||
path: '/exchange/market',
|
||||
availableFor: ['SELLER', 'WHOLESALE', 'FULFILLMENT', 'LOGIST'], // Все роли
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### 5. ИКОНКА И UI ЭЛЕМЕНТЫ
|
||||
|
||||
#### 5.1 Выбор иконки:
|
||||
|
||||
```typescript
|
||||
import { TrendingUp } from 'lucide-react' // Основной вариант - рост, тренды
|
||||
// Альтернативы:
|
||||
// import { Zap } from 'lucide-react' // Энергия, быстрота
|
||||
// import { BarChart3 } from 'lucide-react' // Аналитика, графики
|
||||
// import { Activity } from 'lucide-react' // Активность, пульс
|
||||
```
|
||||
|
||||
#### 5.2 Стилизация в соответствии с дизайн-системой:
|
||||
|
||||
```typescript
|
||||
// Используем существующую Glass Morphism систему
|
||||
<div className="glass-card">
|
||||
<div className="flex items-center gap-3">
|
||||
<TrendingUp className="h-5 w-5 text-primary" />
|
||||
<span className="font-semibold">Биржа</span>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### 6. БЕЗОПАСНОСТЬ И СОВМЕСТИМОСТЬ
|
||||
|
||||
#### 6.1 Проверка существующих зависимостей:
|
||||
|
||||
```bash
|
||||
# Поиск всех ссылок на старые компоненты
|
||||
grep -r "market/investments" src/
|
||||
grep -r "market/market" src/
|
||||
grep -r "/market/investments" src/
|
||||
grep -r "/market/market" src/
|
||||
```
|
||||
|
||||
#### 6.2 Градуальная миграция:
|
||||
|
||||
```typescript
|
||||
// Временный мост-компонент
|
||||
const MarketInvestmentsBridge: FC = () => {
|
||||
// Редирект на новый URL
|
||||
useEffect(() => {
|
||||
router.replace('/exchange/investments')
|
||||
}, [])
|
||||
|
||||
return <div>Перенаправление на новую страницу...</div>
|
||||
}
|
||||
```
|
||||
|
||||
### 7. ТЕСТИРОВАНИЕ И ПРОВЕРКА
|
||||
|
||||
#### 7.1 Чек-лист проверки:
|
||||
|
||||
- [ ] Все ссылки работают корректно
|
||||
- [ ] Редиректы функционируют
|
||||
- [ ] Навигация обновлена во всех кабинетах
|
||||
- [ ] Компоненты отображаются идентично
|
||||
- [ ] Данные загружаются без ошибок
|
||||
- [ ] TypeScript типы корректны
|
||||
|
||||
#### 7.2 Тестирование по ролям:
|
||||
|
||||
```typescript
|
||||
const testScenarios = [
|
||||
{ role: 'SELLER', path: '/exchange' },
|
||||
{ role: 'WHOLESALE', path: '/exchange' },
|
||||
{ role: 'FULFILLMENT', path: '/exchange' },
|
||||
{ role: 'LOGIST', path: '/exchange' },
|
||||
]
|
||||
```
|
||||
|
||||
### 8. ГРАФQL И ДАННЫЕ
|
||||
|
||||
#### 8.1 Анализ существующих компонентов:
|
||||
|
||||
```typescript
|
||||
// ✅ ОБНАРУЖЕНО: Компоненты НЕ ИСПОЛЬЗУЮТ GraphQL
|
||||
// market-investments.tsx - статичные UI карточки
|
||||
// market-business.tsx - статичные UI карточки
|
||||
// Никаких useQuery/useMutation не найдено
|
||||
```
|
||||
|
||||
#### 8.2 Стратегия переноса данных:
|
||||
|
||||
```typescript
|
||||
// Компоненты используют только UI элементы:
|
||||
// - Статичный контент
|
||||
// - Иконки Lucide React
|
||||
// - Glass Morphism карточки
|
||||
// - Никаких внешних API вызовов
|
||||
```
|
||||
|
||||
#### 8.3 Заключение по GraphQL:
|
||||
|
||||
- ❌ **GraphQL запросы НЕ НУЖНЫ** - компоненты статичные
|
||||
- ✅ **Простой перенос** - только UI компоненты
|
||||
- ✅ **Без изменений в resolvers** - данные не загружаются
|
||||
|
||||
### 9. ПЛАН ПОЭТАПНОЙ РЕАЛИЗАЦИИ
|
||||
|
||||
#### Фаза 1: Подготовка
|
||||
|
||||
1. Создание структуры папок
|
||||
2. Анализ зависимостей
|
||||
3. Создание TypeScript интерфейсов
|
||||
|
||||
#### Фаза 2: Создание компонентов
|
||||
|
||||
1. Копирование и адаптация существующих компонентов
|
||||
2. Создание exchange-dashboard.tsx
|
||||
3. Настройка навигации
|
||||
|
||||
#### Фаза 3: Интеграция
|
||||
|
||||
1. Обновление маршрутов
|
||||
2. Настройка редиректов
|
||||
3. Обновление импортов
|
||||
|
||||
#### Фаза 4: Тестирование и очистка
|
||||
|
||||
1. Тестирование всех сценариев
|
||||
2. Удаление дубликатов
|
||||
3. Финальная проверка
|
||||
|
||||
---
|
||||
|
||||
## ✅ ПОДТВЕРЖДЁННЫЕ РЕШЕНИЯ:
|
||||
|
||||
1. **Иконка:** ✅ `TrendingUp` подходит для раздела "Биржа"
|
||||
2. **Позиционирование:** ✅ Размещать прямо перед Settings в сайдбаре
|
||||
3. **GraphQL:** ✅ Изменения НЕ НУЖНЫ - компоненты статичные
|
||||
4. **Уведомления:** ✅ НЕ показывать уведомления о переносе
|
||||
|
||||
## 🎯 ФИНАЛЬНАЯ АРХИТЕКТУРА:
|
||||
|
||||
### Структура переноса:
|
||||
|
||||
```
|
||||
ИЗ: /market (4 вкладки)
|
||||
├── investments ➜ /exchange/investments
|
||||
├── business ➜ /exchange/market
|
||||
├── products ➜ остается в /market
|
||||
└── requests ➜ остается в /market
|
||||
|
||||
В: /exchange (2 вкладки)
|
||||
├── /exchange/investments (было: market-investments.tsx)
|
||||
└── /exchange/market (было: market-business.tsx)
|
||||
```
|
||||
|
||||
### Обновление nav структуры:
|
||||
|
||||
```typescript
|
||||
// sidebar.tsx порядок пунктов:
|
||||
[Home, Supplies, Services, Exchange, Settings, ...]
|
||||
// ↑ новый пункт
|
||||
```
|
||||
|
||||
## 📊 СТАТУС РЕАЛИЗАЦИИ
|
||||
|
||||
**Текущий статус**: ✅ **ПОЛНОСТЬЮ РЕАЛИЗОВАНО**
|
||||
|
||||
**Дата завершения**: 22 августа 2025
|
||||
|
||||
### Выполненные фазы:
|
||||
|
||||
✅ **Фаза 1**: Создана структура папок `src/components/exchange/`
|
||||
✅ **Фаза 2**: Скопированы и адаптированы компоненты из market
|
||||
✅ **Фаза 3**: Обновлена навигация и созданы маршруты
|
||||
✅ **Фаза 4**: Протестировано и очищено
|
||||
|
||||
### Результат реализации:
|
||||
|
||||
- ✅ Раздел "Биржа" доступен во всех кабинетах с иконкой TrendingUp
|
||||
- ✅ Перенесены вкладки "Инвестиции" и "Бизнес" из Маркета в Биржу
|
||||
- ✅ Маркет теперь содержит только "Товары" и "Заявки"
|
||||
- ✅ Сохранена полная функциональность без потери данных
|
||||
- ✅ Безопасная реализация с резервными копиями
|
||||
- ✅ Протестировано - dev сервер запускается корректно
|
||||
- ✅ Типы TypeScript корректны
|
||||
|
||||
### Финальная структура:
|
||||
|
||||
```
|
||||
src/components/exchange/
|
||||
├── exchange-dashboard.tsx ✅ Главная страница Биржи
|
||||
├── tabs/
|
||||
│ ├── investments-tab.tsx ✅ Перенос из market-investments
|
||||
│ └── business-tab.tsx ✅ Перенос из market-business
|
||||
├── types/
|
||||
│ └── exchange.types.ts ✅ TypeScript интерфейсы
|
||||
└── index.ts ✅ Экспорты модуля
|
||||
|
||||
src/app/exchange/page.tsx ✅ Next.js маршрут
|
||||
```
|
||||
|
||||
**ЗАДАЧА ВЫПОЛНЕНА УСПЕШНО!** 🎉
|
@ -36,7 +36,7 @@ interface SupplyOrder {
|
||||
sellerConsumables: Supply[] // Расходники селлера
|
||||
}
|
||||
|
||||
// Упаковочная информация (опциональная)
|
||||
// Параметры поставки (опциональные)
|
||||
packagesCount?: number // Количество грузовых мест
|
||||
volume?: number // Объем груза в м³
|
||||
readyDate?: Date // Дата готовности к отгрузке
|
||||
@ -567,7 +567,7 @@ export class CommercialDataAudit {
|
||||
"quantity": 10
|
||||
// ❌ НЕ видит recipe
|
||||
}],
|
||||
"packagesCount": 2, // ✅ Видит упаковочную информацию
|
||||
"packagesCount": 2, // ✅ Видит параметры поставки
|
||||
"volume": 0.5,
|
||||
// ❌ НЕ видит totalAmount, услуги ФФ, логистику
|
||||
}
|
||||
|
302
docs/business-processes/SUPPLY_PARAMETERS_RULES.md
Normal file
302
docs/business-processes/SUPPLY_PARAMETERS_RULES.md
Normal file
@ -0,0 +1,302 @@
|
||||
# ПРАВИЛА ПАРАМЕТРОВ ПОСТАВКИ
|
||||
|
||||
## 📋 **ОПРЕДЕЛЕНИЕ ПАРАМЕТРОВ ПОСТАВКИ**
|
||||
|
||||
**Параметры поставки** - это все характеристики и данные, которые описывают конкретную поставку товаров в системе SFERA.
|
||||
|
||||
## 🎯 **КЛАССИФИКАЦИЯ ПАРАМЕТРОВ ПОСТАВКИ**
|
||||
|
||||
### **1. ОБЯЗАТЕЛЬНЫЕ ПАРАМЕТРЫ:**
|
||||
- **`id`** - Уникальный идентификатор поставки
|
||||
- **`deliveryDate`** - Дата поставки (когда товары должны быть доставлены)
|
||||
- **`totalAmount`** - Общая стоимость поставки
|
||||
- **`totalItems`** - Количество товаров в поставке
|
||||
- **`organizationId`** - Идентификатор заказчика
|
||||
- **`partnerId`** - Идентификатор поставщика
|
||||
- **`status`** - Статус поставки (PENDING, APPROVED, SHIPPED и т.д.)
|
||||
|
||||
### **2. ЦЕНОВЫЕ ПАРАМЕТРЫ:**
|
||||
- **`totalAmount`** - Общая сумма поставки
|
||||
- **`goodsPrice`** - Стоимость товаров (расчетное поле)
|
||||
- **`servicesPrice`** - Стоимость услуг фулфилмента (расчетное поле)
|
||||
- **`logisticsPrice`** - Стоимость логистических услуг (расчетное поле)
|
||||
- **`sellerConsumablesPrice`** - Стоимость расходников селлера (расчетное поле)
|
||||
- **`ffConsumablesPrice`** - Стоимость расходников фулфилмента (расчетное поле)
|
||||
|
||||
### **3. ТОВАРНЫЕ ПАРАМЕТРЫ:**
|
||||
- **`items[]`** - Массив товаров с количествами и ценами
|
||||
- **`productId`** - ID товара в позиции
|
||||
- **`quantity`** - Количество каждого товара
|
||||
- **`price`** - Цена за единицу товара
|
||||
- **`totalPrice`** - Общая стоимость позиции
|
||||
- **`services[]`** - Массив услуг для товара
|
||||
- **`fulfillmentConsumables[]`** - Расходники фулфилмента для товара
|
||||
- **`sellerConsumables[]`** - Расходники селлера для товара
|
||||
- **`marketplaceCardId`** - ID карточки маркетплейса
|
||||
|
||||
### **4. ЛОГИСТИЧЕСКИЕ ПАРАМЕТРЫ:**
|
||||
- **`packagesCount`** - Количество грузовых мест
|
||||
- **`volume`** - Объём груза в м³
|
||||
- **`routes[]`** - Маршруты доставки
|
||||
- **`fromLocation`** - Точка забора груза
|
||||
- **`toLocation`** - Точка доставки
|
||||
- **`fromAddress`** - Полный адрес забора
|
||||
- **`toAddress`** - Полный адрес доставки
|
||||
- **`distance`** - Расстояние маршрута в км
|
||||
- **`estimatedTime`** - Время доставки в часах
|
||||
- **`logisticsPartnerId`** - ID логистического партнера
|
||||
|
||||
### **5. УПРАВЛЕНЧЕСКИЕ ПАРАМЕТРЫ:**
|
||||
- **`responsibleEmployee`** - Ответственный сотрудник
|
||||
- **`notes`** - Комментарии и дополнительная информация
|
||||
- **`createdAt`** - Дата создания поставки
|
||||
- **`updatedAt`** - Дата последнего обновления
|
||||
- **`fulfillmentCenterId`** - ID фулфилмент центра
|
||||
- **`consumableType`** - Тип расходников
|
||||
|
||||
<!-- ОТКАТ: Расширенная классификация параметров поставки
|
||||
|
||||
### **6. ВРЕМЕННЫЕ ПАРАМЕТРЫ:**
|
||||
- **`deliveryDate`** - Плановая дата доставки
|
||||
- **`readyDate`** - Дата готовности к отгрузке
|
||||
- **`actualDeliveryDate`** - Фактическая дата доставки
|
||||
- **`createdAt`** - Время создания заявки
|
||||
- **`approvedAt`** - Время одобрения поставщиком
|
||||
- **`shippedAt`** - Время отгрузки
|
||||
|
||||
### **7. КОНТАКТНЫЕ ПАРАМЕТРЫ:**
|
||||
- **`supplierContact`** - Контактное лицо поставщика
|
||||
- **`buyerContact`** - Контактное лицо покупателя
|
||||
- **`logisticsContact`** - Контактное лицо логистики
|
||||
- **`fulfillmentContact`** - Контактное лицо фулфилмента
|
||||
|
||||
### **8. АДРЕСНЫЕ ПАРАМЕТРЫ:**
|
||||
- **`pickupAddress`** - Адрес забора груза
|
||||
- **`deliveryAddress`** - Адрес доставки
|
||||
- **`warehouseLocation`** - Местоположение склада
|
||||
- **`marketLocation`** - Адрес торговой точки
|
||||
|
||||
### **9. КАЧЕСТВЕННЫЕ ПАРАМЕТРЫ:**
|
||||
- **`qualityRequirements`** - Требования к качеству товаров
|
||||
- **`temperatureConditions`** - Температурные условия хранения/транспортировки
|
||||
- **`handlingInstructions`** - Инструкции по обращению с грузом
|
||||
- **`packagingType`** - Тип упаковки товаров
|
||||
- **`fragileGoods`** - Отметка о хрупких товарах
|
||||
|
||||
### **10. ФИНАНСОВЫЕ ПАРАМЕТРЫ:**
|
||||
- **`paymentTerms`** - Условия оплаты
|
||||
- **`paymentMethod`** - Способ оплаты
|
||||
- **`currency`** - Валюта расчетов
|
||||
- **`taxRate`** - Налоговая ставка
|
||||
- **`invoiceNumber`** - Номер счета
|
||||
- **`paymentStatus`** - Статус оплаты
|
||||
|
||||
### **11. ТЕХНИЧЕСКИЕ ПАРАМЕТРЫ:**
|
||||
- **`supplyOrderId`** - Уникальный идентификатор поставки
|
||||
- **`supplierOrderNumber`** - Внутренний номер заказа поставщика
|
||||
- **`trackingNumber`** - Трек-номер для отслеживания
|
||||
- **`barcodes`** - Штрих-коды товаров
|
||||
- **`rfidTags`** - RFID метки для автоматизации
|
||||
|
||||
### **12. АНАЛИТИЧЕСКИЕ ПАРАМЕТРЫ:**
|
||||
- **`profitMargin`** - Маржинальность поставки
|
||||
- **`supplierRating`** - Рейтинг поставщика
|
||||
- **`deliveryReliability`** - Надежность доставки
|
||||
- **`orderPriority`** - Приоритет заказа
|
||||
- **`seasonalFactor`** - Сезонный коэффициент
|
||||
|
||||
-->
|
||||
|
||||
## 🔄 **ЖИЗНЕННЫЙ ЦИКЛ ПАРАМЕТРОВ ПОСТАВКИ**
|
||||
|
||||
### **Этап 1: Создание поставки (SELLER)**
|
||||
```typescript
|
||||
// Селлер указывает базовые параметры поставки
|
||||
{
|
||||
deliveryDate: "2025-08-25",
|
||||
totalItems: 100,
|
||||
items: [...products],
|
||||
partnerId: "supplier-123",
|
||||
organizationId: "seller-456"
|
||||
}
|
||||
```
|
||||
|
||||
### **Этап 2: Одобрение поставщиком (WHOLESALE)**
|
||||
```typescript
|
||||
// Поставщик может дополнить параметры поставки
|
||||
{
|
||||
status: "SUPPLIER_APPROVED",
|
||||
packagesCount: 3, // Новый параметр
|
||||
volume: 1.2, // Новый параметр
|
||||
readyDate: "2025-08-24", // Новый параметр
|
||||
notes: "Хрупкий груз" // Новый параметр
|
||||
}
|
||||
```
|
||||
|
||||
### **Этап 3: Логистическое планирование (LOGIST)**
|
||||
```typescript
|
||||
// Логистика использует параметры для расчетов
|
||||
{
|
||||
logisticsPrice: calculateByVolume(volume, distance),
|
||||
routes: [
|
||||
{
|
||||
from: "Садовод",
|
||||
to: "ФФ Центр",
|
||||
packagesCount: 3,
|
||||
volume: 1.2
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 🛡️ **ПРАВИЛА БЕЗОПАСНОСТИ ПАРАМЕТРОВ**
|
||||
|
||||
### **Видимость по ролям:**
|
||||
|
||||
| Параметр поставки | SELLER | WHOLESALE | FULFILLMENT | LOGIST |
|
||||
|------------------|--------|-----------|-------------|---------|
|
||||
| deliveryDate | ✅ | ✅ | ✅ | ✅ |
|
||||
| totalAmount | ✅ | ❌ | ❌ | ❌ |
|
||||
| productPrice | ✅ | ✅ | ❌ | ❌ |
|
||||
| packagesCount | ✅ | ✅ | ✅ | ✅ |
|
||||
| volume | ✅ | ✅ | ✅ | ✅ |
|
||||
| recipe | ✅ | ❌ | ✅ | ❌ |
|
||||
| logisticsPrice | ✅ | ❌ | ✅ | ✅ |
|
||||
|
||||
### **Права на изменение:**
|
||||
|
||||
- **SELLER**: Может изменять до одобрения поставщиком
|
||||
- **WHOLESALE**: Может добавлять логистические параметры при одобрении
|
||||
- **FULFILLMENT**: Не может изменять, только просматривать
|
||||
- **LOGIST**: Может добавлять маршруты и логистические расчеты
|
||||
|
||||
## 🎛️ **UI КОМПОНЕНТЫ ДЛЯ ПАРАМЕТРОВ ПОСТАВКИ**
|
||||
|
||||
### **Форма ввода параметров поставщиком:**
|
||||
|
||||
```jsx
|
||||
<div className="supply-parameters-form">
|
||||
<h3>Параметры поставки</h3>
|
||||
|
||||
{/* Основные параметры */}
|
||||
<Input name="deliveryDate" label="Дата поставки" type="date" required />
|
||||
<Input name="totalAmount" label="Общая стоимость" type="number" readOnly />
|
||||
|
||||
{/* Логистические параметры (опционально) */}
|
||||
<Input name="packagesCount" label="Количество грузовых мест" type="number" />
|
||||
<Input name="volume" label="Объём груза (м³)" type="number" step="0.01" />
|
||||
|
||||
{/* Дополнительные параметры */}
|
||||
<Input name="readyDate" label="Дата готовности" type="date" />
|
||||
<Textarea name="notes" label="Комментарии к поставке" />
|
||||
</div>
|
||||
```
|
||||
|
||||
### **Отображение в таблице заявок:**
|
||||
|
||||
```jsx
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Дата поставки</TableHead>
|
||||
<TableHead>Количество товаров</TableHead>
|
||||
<TableHead>Стоимость товаров</TableHead>
|
||||
{userRole !== 'WHOLESALE' && <TableHead>Общая стоимость</TableHead>}
|
||||
<TableHead>Параметры логистики</TableHead>
|
||||
<TableHead>Статус</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{supplies.map(supply => (
|
||||
<TableRow key={supply.id}>
|
||||
<TableCell>{supply.deliveryDate}</TableCell>
|
||||
<TableCell>{supply.totalItems}</TableCell>
|
||||
<TableCell>{formatCurrency(supply.productPrice)}</TableCell>
|
||||
{userRole !== 'WHOLESALE' && (
|
||||
<TableCell>{formatCurrency(supply.totalAmount)}</TableCell>
|
||||
)}
|
||||
<TableCell>
|
||||
{supply.packagesCount && `${supply.packagesCount} мест`}
|
||||
{supply.volume && ` • ${supply.volume} м³`}
|
||||
</TableCell>
|
||||
<TableCell><StatusBadge status={supply.status} /></TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
```
|
||||
|
||||
## 📊 **ВАЛИДАЦИЯ ПАРАМЕТРОВ ПОСТАВКИ**
|
||||
|
||||
### **Серверная валидация:**
|
||||
|
||||
```typescript
|
||||
function validateSupplyParameters(params: SupplyParameters) {
|
||||
// Обязательные параметры
|
||||
if (!params.deliveryDate) throw new Error('Дата поставки обязательна')
|
||||
if (!params.totalItems || params.totalItems <= 0) {
|
||||
throw new Error('Количество товаров должно быть больше 0')
|
||||
}
|
||||
|
||||
// Логистические параметры
|
||||
if (params.packagesCount && params.packagesCount <= 0) {
|
||||
throw new Error('Количество грузовых мест должно быть положительным')
|
||||
}
|
||||
|
||||
if (params.volume && params.volume <= 0) {
|
||||
throw new Error('Объём груза должен быть положительным')
|
||||
}
|
||||
|
||||
// Даты
|
||||
if (params.readyDate && params.deliveryDate) {
|
||||
if (new Date(params.readyDate) > new Date(params.deliveryDate)) {
|
||||
throw new Error('Дата готовности не может быть позже даты поставки')
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔍 **ПОИСК И ФИЛЬТРАЦИЯ ПО ПАРАМЕТРАМ**
|
||||
|
||||
### **GraphQL запрос с фильтрами:**
|
||||
|
||||
```graphql
|
||||
query GetSuppliesByParameters(
|
||||
$deliveryDateFrom: DateTime
|
||||
$deliveryDateTo: DateTime
|
||||
$minAmount: Float
|
||||
$maxAmount: Float
|
||||
$status: SupplyStatus
|
||||
$hasLogisticsParams: Boolean
|
||||
) {
|
||||
mySupplyOrders(
|
||||
filters: {
|
||||
deliveryDate: { gte: $deliveryDateFrom, lte: $deliveryDateTo }
|
||||
totalAmount: { gte: $minAmount, lte: $maxAmount }
|
||||
status: $status
|
||||
packagesCount: { isNull: $hasLogisticsParams }
|
||||
}
|
||||
) {
|
||||
id
|
||||
deliveryDate
|
||||
totalAmount
|
||||
totalItems
|
||||
packagesCount
|
||||
volume
|
||||
status
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📈 **АНАЛИТИКА ПО ПАРАМЕТРАМ ПОСТАВКИ**
|
||||
|
||||
### **Ключевые метрики:**
|
||||
- Средний объём поставки (в м³)
|
||||
- Среднее количество грузовых мест
|
||||
- Распределение по стоимости поставок
|
||||
- Время цикла от создания до доставки
|
||||
- Процент поставок с дополнительными параметрами
|
||||
|
||||
---
|
||||
|
||||
*Все параметры поставки служат для оптимизации логистических процессов и обеспечения прозрачности цепочки поставок в экосистеме SFERA.*
|
Reference in New Issue
Block a user