# ПРАВИЛА КАБИНЕТА ФУЛФИЛМЕНТА (FULFILLMENT)

> ⚠️ **ВАЖНО**: Это файл с техническими деталями кабинета фулфилмента.
> Общие бизнес-правила находятся в **[rules-complete.md](./rules-complete.md)**

## Когда использовать этот файл:

- Работа с компонентами `/warehouse`, `/fulfillment-supplies`, `/services`, `/employees`
- GraphQL запросы для фулфилмента
- UI/UX специфика кабинета фулфилмента
- Технические детали реализации услуг и логистики

## 1. 🏭 СТРУКТУРА КАБИНЕТА ФУЛФИЛМЕНТА

### 1.1 Основные разделы

**ФУЛФИЛМЕНТ (`FULFILLMENT`)** имеет доступ к следующим разделам:

- **Склад** (`/warehouse`) - управление товарами по модулям
- **Поставки** (`/fulfillment-supplies`) - обработка поставок
- **Услуги** (`/services`) - управление услугами и расходниками
- **Сотрудники** (`/employees`) - управление персоналом
- **Статистика** (`/fulfillment-statistics`) - аналитика фулфилмента
- **Партнеры** (`/partners`) - управление контрагентами
- **Мессенджер** (`/messenger`) - связь с партнерами
- **Настройки** (`/settings`) - профиль и настройки
- **Экономика** (`/economics`) - финансовая аналитика

### 1.2 Навигация и роутинг

#### При входе в систему:

```typescript
switch (user?.organization?.type) {
  case 'FULFILLMENT':
    router.push('/warehouse') // Направляем на склад
    break
}
```

#### Специальная логика роутинга:

- **МАКСИМАЛЬНЫЕ ПРАВА**: Доступ ко ВСЕМ разделам системы
- **АДАПТИВНАЯ НАВИГАЦИЯ**: Sidebar изменяется в зависимости от типа организации
- **СПЕЦИАЛЬНЫЙ РОУТИНГ**: `/fulfillment-supplies` вместо `/supplies`

> 📖 **Бизнес-логика роутинга**: См. [rules-complete.md#4-система-ролей-и-доступов](./rules-complete.md#4--система-ролей-и-доступов)

## 2. 🎨 UI/UX КОМПОНЕНТЫ

### 2.1 Dashboard компоненты

#### Основные компоненты кабинета:

- `FulfillmentWarehouseDashboard` - склад по модулям
- `FulfillmentSuppliesDashboard` - поставки фулфилмента
- `ServicesManagement` - управление услугами
- `FulfillmentStatistics` - статистика и аналитика
- `EmployeeManagement` - управление сотрудниками

#### Wrapper-компоненты:

- `HomePageWrapper` - маршрутизация по типам организаций
- `EconomicsPageWrapper` - адаптивная экономика по кабинетам

#### Специализированные компоненты:

- `WarehouseModuleCard` - карточка модуля склада
- `ServiceCard` - карточка услуги
- `EmployeeCard` - карточка сотрудника
- `FulfillmentStats` - статистика фулфилмента
- `LogisticsRouteCard` - карточка маршрута доставки

### 2.2 Архитектурные особенности

#### Технические правила отображения:

```tsx
// GraphQL проверки
const { data } = useQuery(GET_FULFILLMENT_DATA, {
  skip: user?.organization?.type !== 'FULFILLMENT'
})

// Условное отображение
{user?.organization?.type === "FULFILLMENT" && (
  <FulfillmentExclusiveComponent />
)}

// Адаптивные отступы
const margin = getSidebarMargin()

// Полинг данных для реального времени
const { data } = useQuery(GET_FULFILLMENT_STATS, {
  pollInterval: 60000 // Обновление каждую минуту
})
```

### 2.3 Система учета склада (3-уровневая иерархия)

#### Структура данных:

```
🔵 УРОВЕНЬ 1: МАГАЗИНЫ
    ↓
🟢 УРОВЕНЬ 2: ТОВАРЫ (зеленый - green-500)
    ↓
🟠 УРОВЕНЬ 3: ВАРИАНТЫ ТОВАРОВ (оранжевый - orange-500)
```

#### Цветовое кодирование:

- Каждый уровень имеет цветной индикатор увеличивающегося размера
- Цветная левая граница с увеличивающимся отступом и толщиной
- Скроллбары в цвете уровня
- Контрастный цвет текста для читаемости

## 3. 📊 ФУНКЦИОНАЛЬНЫЕ ВОЗМОЖНОСТИ

> 📖 **Бизнес-правила**: См. [rules-complete.md#11-кабинет-фулфилмента](./rules-complete.md#11--кабинет-фулфилмента) для правил workflow и процессов

### 3.1 Структура склада по модулям (ОБЯЗАТЕЛЬНАЯ ПОСЛЕДОВАТЕЛЬНОСТЬ)

1. **📦 ПРОДУКТЫ** - готовые к отправке товары
2. **🛒 ТОВАРЫ** - базовые товары от поставщиков
   - **"На складе"** - готовы к обработке
   - **"В обработке"** - в процессе создания продукта
3. **❌ БРАК** - товары с дефектами, требуют утилизации
4. **↩️ ВОЗВРАТЫ С ПВЗ** - возвращенные товары, к обработке
5. **🎯 РАСХОДНИКИ СЕЛЛЕРОВ** - материалы для селлеров
6. **⚙️ РАСХОДНИКИ ФУЛФИЛМЕНТА** - операционные материалы (КЛИКАБЕЛЬНЫЙ модуль)

### 3.2 Система учета склада

#### Показатели движения (дополнительные значения):

- **ПРИБЫЛО** - количество поступивших на склад за период
- **УБЫЛО** - количество списанных со склада за период

#### Текущие остатки (основные значения):

- **ФОРМУЛА**: Основные значения = Предыдущие остатки + Прибыло - Убыло
- **ОБНОВЛЕНИЕ**: В реальном времени с изменениями за сутки
- **ИСТОЧНИК**: GraphQL query `GET_FULFILLMENT_WAREHOUSE_STATS`

### 3.3 Поставки фулфилмента (`/fulfillment-supplies`)

#### Структура: 2 основные вкладки

**A) 🛒 ПОСТАВКИ ТОВАРОВ**:
- **Детализированные товары ФФ** - планы и факты поставок с маршрутами
- **Товары ФФ** - общие поставки товаров от селлеров
- **Возвраты с ПВЗ** - обработка возвращенных товаров

**B) 🔧 ПОСТАВКИ РАСХОДНИКОВ**:
- **Заказы расходников** - управление заказами от селлеров
- **Расходники селлеров** - материалы для клиентов
- **Создание поставок** - формирование новых поставок расходников

#### Workflow поставок товаров:

1. **Planned** - поставка запланирована
2. **In-transit** - товар в пути
3. **Delivered** - доставлен на склад
4. **Completed** - обработка завершена

### 3.4 Услуги фулфилмента (`/services`)

#### Архитектура интеграции с системой

**СВЯЗЬ С РЕЦЕПТУРАМИ СЕЛЛЕРОВ:**

```
СЕЛЛЕР (создание поставки)
    └── Рецептура
         ├── Товар (от поставщика)
         ├── Услуги фулфилмента ← CRUD в разделе Услуги
         ├── Расходники селлера
         └── Расходники фулфилмента ← ТОЛЬКО с установленной ценой
                    ↓
ФУЛФИЛМЕНТ (обработка)
    ├── Входящие поставки → Поставки расходников (создание)
    └── Услуги → Расходники (установка цены за единицу)
```

#### Структура: 3 обязательные вкладки

**A) 🛠️ УСЛУГИ** (`defaultValue="services"`):
- **Полный CRUD**: создание, редактирование, удаление услуг
- **Поля**: `name`, `description`, `price`, `imageUrl`
- **Glass Upload Zone**: элегантная загрузка изображений
- **Назначение**: каталог услуг для рецептур селлеров

**B) 🚚 ЛОГИСТИКА**:
- **Полный CRUD**: маршруты доставки
- **Поля**: откуда → куда, тарификация до/свыше 1м³
- **Группированные локации**:
  - Мой фулфилмент (название организации)
  - Рынки (предустановленные)
  - Склады Wildberries
  - Склады Ozon
- **Glass Upload Zone**: для изображений маршрутов

**C) 📦 РАСХОДНИКИ** (**❌ БЕЗ СОЗДАНИЯ**):
- **ТОЛЬКО ПРОСМОТР** расходников с фулфилмент-склада
- **ЕДИНСТВЕННОЕ РЕДАКТИРУЕМОЕ ПОЛЕ**: `pricePerUnit` - цена за единицу для рецептур
- **UI подсветка**: "Цена за 1 {unit}" (например, "Цена за 1 шт")
- **Автоматическая синхронизация** при приеме поставки расходников
- **Glass Upload Zone**: для обновления изображений расходников

#### Workflow расходников:

**ШАГ 1 - СОЗДАНИЕ**: Только через "Входящие поставки → Поставки расходников фулфилмента"
**ШАГ 2 - СИНХРОНИЗАЦИЯ**: При приеме на склад → автоматически в Услуги/Расходники
**ШАГ 3 - ЦЕНООБРАЗОВАНИЕ**: Установка цены за единицу в разделе Услуги
**ШАГ 4 - ИСПОЛЬЗОВАНИЕ**: Доступны в рецептурах селлеров

#### Правила видимости в рецептурах:

**В РЕЦЕПТУРАХ СЕЛЛЕРОВ ПОКАЗЫВАЮТСЯ ТОЛЬКО:**
- `isAvailable = true` (есть на складе)
- `pricePerUnit != null` (цена установлена)

**НЕ ПОКАЗЫВАЮТСЯ:**
- Расходники без цены (`pricePerUnit = null`)
- Удаленные со склада (`isAvailable = false`)

### 3.5 Разделение цен закупки и продажи

**КРИТИЧЕСКОЕ ПРАВИЛО**: Расходники фулфилмента имеют **ДВЕ РАЗНЫЕ ЦЕНЫ**:

1. **ЦЕНА ЗАКУПКИ** (`Supply.price`) - цена покупки у поставщика
2. **ЦЕНА ПРОДАЖИ** (`Supply.pricePerUnit`) - цена продажи селлерам

#### Поля в базе данных:

```prisma
model Supply {
  price        Decimal  @db.Decimal(10, 2) // Цена закупки у поставщика (НЕИЗМЕННАЯ)
  pricePerUnit Decimal? @db.Decimal(10, 2) // Цена продажи селлерам (устанавливается фулфилментом)
}
```

#### Правила отображения по разделам:

**РАЗДЕЛ "СКЛАД → РАСХОДНИКИ ФУЛФИЛМЕНТА"**:
- Показывает `Supply.price` (цена закупки)
- Цена ТОЛЬКО ДЛЯ ЧТЕНИЯ, нельзя изменять
- Отражает историческую стоимость приобретения

**РАЗДЕЛ "УСЛУГИ → РАСХОДНИКИ"**:
- Показывает и редактирует `Supply.pricePerUnit` (цена продажи)
- Единственное место где можно изменить цену для селлеров
- Влияет на рецептуры и расчеты для селлеров

#### Бизнес-логика создания:

```typescript
// ПРИ ПОСТУПЛЕНИИ ОТ ПОСТАВЩИКА:
const supply = await prisma.supply.create({
  data: {
    price: item.price, // Цена поставщика → ЗАФИКСИРОВАНА
    pricePerUnit: null, // Цена продажи → ПУСТАЯ
  },
})

// УСТАНОВКА ЦЕНЫ ПРОДАЖИ (в разделе "Услуги"):
const updated = await prisma.supply.update({
  data: {
    pricePerUnit: newPrice, // ТОЛЬКО цена продажи
    // price НЕ ТРОГАЕМ - остается цена закупки
  },
})
```

### 3.6 Сотрудники фулфилмента (`/employees`)

#### Структура: 2 основные вкладки

**A) 👥 СОТРУДНИКИ** (`defaultValue="combined"`):

**Управление персоналом**:
- **CRUD операции**: создание, редактирование, удаление сотрудников
- **Статусы сотрудников**: `ACTIVE`, `VACATION`, `SICK`, `FIRED`
- **Формы добавления**: Компактная (`showCompactForm`) / Полная форма
- **Поиск и фильтрация** по имени, должности, статусу

**Табель рабочего времени**:
- **Навигация по месяцам**: текущий год/месяц с кнопками ←/→
- **Отметки по дням**: статус дня и количество отработанных часов

**B) 📋 ОТЧЕТЫ** (`value="reports"`):
- **Сводные отчеты** по сотрудникам за период
- **Экспорт данных** табеля
- **Аналитика рабочего времени**

### 3.7 Статистика фулфилмента (`/fulfillment-statistics`)

#### Блоки аналитики (сворачиваемые):

**1. НАКОПЛЕННАЯ СТАТИСТИКА** (`allTime: true`):
- Обработано товаров (общий объем)
- Выявлено брака (всего единиц)
- Поставок получено
- Общий доход (за все время)
- Выполнено заказов (успешных отгрузок)
- Удовлетворенность клиентов (средний рейтинг)

**2. ОТГРУЗКА НА ПЛОЩАДКИ** (`marketplaces: true`):
- Отправлено на Wildberries
- Отправлено на Ozon
- Отправлено на другие площадки

**3. АНАЛИТИКА ПРОИЗВОДИТЕЛЬНОСТИ** (`performance: false`):
- Среднее время обработки (на единицу товара)
- Уровень брака (от общего объема)
- Уровень возвратов (возвраты с площадок)
- Удовлетворенность клиентов

## 4. 🛠️ GRAPHQL API

### 4.1 Основные запросы (Queries)

#### Получение статистики склада:

```graphql
query GetFulfillmentWarehouseStats {
  fulfillmentWarehouseStats {
    products {
      total
      received
      shipped
    }
    supplies {
      onStock
      inProcessing
    }
    defects {
      total
      pending
    }
    returns {
      pending
      processed
    }
  }
}
```

#### Получение услуг фулфилмента:

```graphql
query GetMyServices {
  myServices {
    id
    name
    description
    price
    imageUrl
    isActive
  }
}
```

#### Получение расходников с ценами:

```graphql
query GetMySupplies {
  mySupplies {
    id
    name
    price          # Цена закупки (read-only)
    pricePerUnit   # Цена продажи (editable)
    unit
    isAvailable
    warehouseConsumableId
  }
}
```

#### Получение логистических маршрутов:

```graphql
query GetMyLogistics {
  myLogistics {
    id
    fromLocation
    toLocation
    tariffUnder1m3
    tariffOver1m3
    description
  }
}
```

#### Получение сотрудников:

```graphql
query GetEmployees {
  employees {
    id
    name
    position
    status
    schedule {
      date
      hoursWorked
      status
    }
  }
}
```

### 4.2 Мутации (Mutations)

#### Создание услуги:

```graphql
mutation CreateService($input: ServiceInput!) {
  createService(input: $input) {
    success
    service {
      id
      name
      description
      price
      organization {
        id
        name
        fullName
      }
    }
  }
}
```

#### Обновление цены расходника:

```graphql
mutation UpdateSupplyPrice($supplyId: ID!, $pricePerUnit: Float!) {
  updateSupplyPrice(id: $supplyId, pricePerUnit: $pricePerUnit) {
    success
    supply {
      id
      pricePerUnit
      isAvailable
    }
  }
}
```

#### Создание логистического маршрута:

```graphql
mutation CreateLogistics($input: LogisticsInput!) {
  createLogistics(input: $input) {
    success
    logistics {
      id
      fromLocation
      toLocation
      tariffUnder1m3
      tariffOver1m3
      organization {
        id
        name
        fullName
      }
    }
  }
}
```

#### Управление сотрудниками:

```graphql
mutation CreateEmployee($input: EmployeeInput!) {
  createEmployee(input: $input) {
    success
    employee {
      id
      name
      position
      status
    }
  }
}

mutation UpdateEmployeeSchedule($employeeId: ID!, $date: String!, $hoursWorked: Int!, $status: String!) {
  updateEmployeeSchedule(employeeId: $employeeId, date: $date, hoursWorked: $hoursWorked, status: $status) {
    success
    schedule {
      date
      hoursWorked
      status
    }
  }
}
```

### 4.3 Специальные запросы для рецептур

#### Расходники доступные для рецептур (только с ценой):

```graphql
query GetAvailableSuppliesForRecipe {
  availableSuppliesForRecipe {
    id
    name
    pricePerUnit  # Только те что != null
    unit
    imageUrl
  }
}
```

#### GraphQL типы:

```graphql
type Supply {
  id: ID!
  name: String!
  price: Float!              # Цена закупки (неизменная)
  pricePerUnit: Float        # Цена продажи (может быть null)
  unit: String!              # "шт", "кг", "м"
  isAvailable: Boolean!      # Статус на складе
  warehouseConsumableId: ID! # Связь со складом
  imageUrl: String
}

type Service {
  id: ID!
  name: String!
  description: String
  price: Float!
  imageUrl: String
  organization: Organization!
}

type Logistics {
  id: ID!
  fromLocation: String!
  toLocation: String!
  tariffUnder1m3: Float!
  tariffOver1m3: Float!
  description: String
  organization: Organization!
}
```

## 5. 📁 ТЕХНИЧЕСКИЕ КОМПОНЕНТЫ

### 5.1 Расположение компонентов

```
src/components/
├── fulfillment/           # Компоненты фулфилмента
│   ├── fulfillment-warehouse-dashboard.tsx
│   ├── fulfillment-supplies-dashboard.tsx  
│   ├── fulfillment-statistics.tsx
│   └── warehouse-module-card.tsx
├── services/              # Компоненты услуг
│   ├── services-management.tsx
│   ├── service-card.tsx
│   ├── logistics-management.tsx
│   └── consumables-pricing.tsx
├── employees/             # Компоненты сотрудников
│   ├── employee-management.tsx
│   ├── employee-card.tsx
│   ├── employee-schedule.tsx
│   └── employee-reports.tsx
└── economics/             # Экономика
    └── fulfillment-economics-page.tsx
```

### 5.2 Страницы (Pages)

```
src/app/
├── warehouse/
│   └── page.tsx           # Склад фулфилмента
├── fulfillment-supplies/
│   └── page.tsx           # Поставки фулфилмента
├── services/
│   └── page.tsx           # Услуги и расходники
├── employees/
│   └── page.tsx           # Сотрудники
└── fulfillment-statistics/
    └── page.tsx           # Статистика
```

## 6. 🚨 ТЕХНИЧЕСКИЕ ПРАВИЛА И ОГРАНИЧЕНИЯ

> 📖 **Workflow процессов**: См. [rules-complete.md#11-кабинет-фулфилмента](./rules-complete.md#11--кабинет-фулфилмента) для бизнес-процессов

### 6.1 Обязательные проверки:

- Проверка типа организации: `organization.type === 'FULFILLMENT'`
- Валидация прав доступа на уровне GraphQL резолверов
- Проверка наличия товаров на складе перед отгрузкой
- Контроль цен расходников перед отображением в рецептурах

### 6.2 Правила безопасности доступа:

#### Контроль на уровне компонентов:

```typescript
{user?.organization?.type === "FULFILLMENT" && (
  <FulfillmentWarehouseDashboard />
)}

// Для полинга данных
const { data } = useQuery(GET_FULFILLMENT_STATS, {
  skip: user?.organization?.type !== 'FULFILLMENT',
  pollInterval: 60000
})
```

#### Проверки в GraphQL резолверах:

```typescript
// Проверка что пользователь - фулфилмент
if (context.user.organization.type !== 'FULFILLMENT') {
  throw new Error('Access denied: Fulfillment access required')
}

// Проверка доступа к своим услугам
const service = await prisma.service.findFirst({
  where: {
    id: serviceId,
    organizationId: context.user.organizationId,
  },
})

// Обязательное включение organization в ответы
const updated = await prisma.service.update({
  where: { id: serviceId },
  data: input,
  include: { organization: true }, // ОБЯЗАТЕЛЬНО!
})
```

### 6.3 Запрещено:

- Создавать расходники в разделе "Услуги" (только через поставки)
- Изменять цену закупки (`Supply.price`) - она фиксируется при поступлении
- Показывать в рецептурах расходники без установленной цены продажи
- Удалять услуги, используемые в активных рецептурах

### 6.4 Правила создания и ценообразования:

- **Услуги**: Создаются фулфилментом с установленной ценой
- **Расходники**: Создаются только при поступлении от поставщиков
- **Цена продажи**: Устанавливается отдельно в разделе Услуги
- **Логистика**: Тарификация до/свыше 1м³ обязательна

### 6.5 Правила фулфилмента

**ОБЯЗАТЕЛЬНО**:
- Установка цен на расходники перед доступностью селлерам
- Контроль качества товаров при приемке
- Своевременная обработка возвратов
- Ведение учета движения товаров по модулям
- Управление персоналом и рабочим временем

**ЗАПРЕЩЕНО**:
- Отгружать товары без подтверждения наличия
- Создавать расходники минуя систему поставок
- Изменять цены закупки после поступления товара
- Показывать в рецептурах неактивные расходники
- Нарушать последовательность модулей склада

**ИНТЕГРАЦИЯ С ПАРТНЕРАМИ**:
- Фулфилмент видит всех партнеров системы
- Принимает поставки от всех типов организаций
- Предоставляет услуги селлерам через рецептуры
- Все взаимодействия фиксируются в системе уведомлений

### 6.6 АВТОМАТИЧЕСКИЕ ЗАПИСИ В ТАБЛИЦЕ СКЛАДА ПРИ НОВОМ ПАРТНЕРСТВЕ

#### **ПРАВИЛО АВТОСОЗДАНИЯ ЗАПИСЕЙ В СКЛАДЕ**

**ТРИГГЕР**: При создании нового партнерства с селлером (`SELLER`) автоматически создается запись в таблице склада фулфилмента.

**УСЛОВИЕ СРАБАТЫВАНИЯ**:
- Новая организация типа `SELLER` становится партнером фулфилмента
- Создание происходит через любой механизм партнерства:
  - Партнерские ссылки (`?partner=REFERRAL_CODE`)
  - Коммерческие взаимодействия
  - Прямое добавление в контрагенты

#### **АВТОМАТИЧЕСКИ СОЗДАВАЕМЫЕ ДАННЫЕ**

**Структура записи в таблице склада**:

```typescript
// StoreData - верхний уровень (СИНИЙ УРОВЕНЬ)
interface AutoCreatedStoreEntry {
  id: string                    // Генерируется автоматически
  storeName: string            // Название организации селлера
  storeOwner: string          // ИНН или название селлера  
  storeImage?: string         // Логотип организации (если есть)
  storeQuantity: number       // 0 (пока нет поставок)
  products: ProductItem[]     // Пустой массив изначально
}
```

#### **ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ**:

- **storeName**: `organization.fullName` или `organization.name`
- **storeOwner**: `organization.inn` или `organization.fullName`  
- **storeImage**: `organization.logoUrl` (если заполнено)
- **storeQuantity**: `0` (нет поставок)
- **products**: `[]` (пустой массив)
- **Все вложенные количества**: `0`

#### **БИЗНЕС-ЛОГИКА ОБНОВЛЕНИЯ**

**ПРИ ПЕРВОЙ ПОСТАВКЕ ОТ СЕЛЛЕРА**:
```typescript
// Автоматически обновляются значения:
storeEntry.storeQuantity = totalProductsReceived
storeEntry.products = [
  {
    id: generatedId,
    productName: supply.productName,
    productQuantity: supply.quantity,
    productPlace: supply.warehouseLocation || 'A1-1',
    variants: [] // Заполняется при обработке вариантов
  }
]
```

**ОТОБРАЖЕНИЕ В ТАБЛИЦЕ СКЛАДА**:
- Новые партнеры отображаются сразу после создания партнерства
- Показывают нулевые значения до первых поставок
- Цветовое кодирование: СИНИЙ уровень (store level)
- Размещаются в самом верху таблицы

#### **ТЕХНИЧЕСКАЯ РЕАЛИЗАЦИЯ**

**GraphQL мутация (автоматический вызов)**:
```graphql
mutation AutoCreateWarehouseEntry($partnerId: ID!) {
  autoCreateWarehouseEntry(partnerId: $partnerId) {
    success
    warehouseEntry {
      id
      storeName
      storeOwner
      storeImage
      storeQuantity
    }
  }
}
```

**Триггер на создание партнерства**:
```typescript
// При создании нового партнера-селлера
const createPartnership = async (sellerId: string, fulfillmentId: string) => {
  // 1. Создаем партнерство
  const partnership = await createPartnership(sellerId, fulfillmentId)
  
  // 2. Автоматически создаем запись в складе
  if (partnership.success) {
    await autoCreateWarehouseEntry(sellerId)
  }
}
```

#### **ПРАВИЛА ОТОБРАЖЕНИЯ**

**В ТАБЛИЦЕ СКЛАДА ФУЛФИЛМЕНТА**:
- ✅ Показывать всех партнеров-селлеров (даже с нулевыми поставками)
- ✅ Новые партнеры размещаются в самом верху таблицы
- ✅ Стандартное цветовое кодирование для всех партнеров

**ЦВЕТОВОЕ КОДИРОВАНИЕ**:
- **Синий уровень** (партнеры): стандартное отображение для всех
- **Обычный белый цвет текста**: для всех партнеров независимо от статуса поставок

**КООРДИНАТНАЯ СИСТЕМА**:
- Новым партнерам резервируется место: `Quantity: 0 | Location: -`
- При первой поставке координаты назначаются: `A1-1`, `A1-2`, и т.д.

#### **ОБЯЗАТЕЛЬНЫЕ ПОЛЯ ДЛЯ ПАРТНЕРОВ**

**МИНИМАЛЬНЫЕ ТРЕБОВАНИЯ**:
```prisma
model Organization {
  id       String  @id @default(cuid())
  name     String  // ОБЯЗАТЕЛЬНО для storeName
  fullName String? // Приоритет для storeName
  inn      String? // Для storeOwner
  logoUrl  String? // Для storeImage
  type     OrganizationType // SELLER
}
```

**ВАЛИДАЦИЯ ПРИ СОЗДАНИИ ПАРТНЕРСТВА**:
- Проверка что организация типа `SELLER`
- Проверка что не существует дубликатов в складе
- Генерация уникального ID для записи склада

#### **ИНТЕГРАЦИЯ С СУЩЕСТВУЮЩИМИ КОМПОНЕНТАМИ**

**В компоненте таблицы склада**:
```typescript
// Сортировка: новые партнеры в верху таблицы
const sortStores = (stores: StoreData[]) => {
  return stores.sort((a, b) => {
    // Новые партнеры (quantity = 0) в самом верху
    if (a.storeQuantity === 0 && b.storeQuantity > 0) return -1
    if (a.storeQuantity > 0 && b.storeQuantity === 0) return 1
    
    // Остальная сортировка по количеству или дате
    return b.storeQuantity - a.storeQuantity
  })
}
```

**В GraphQL запросах склада**:
```graphql
query GetWarehouseData {
  warehouseData {
    stores {
      id
      storeName
      storeOwner  
      storeImage
      storeQuantity
      partnershipDate   # Для сортировки новых партнеров
      products {
        # Существующая структура
      }
    }
  }
}
```

> 📖 **Критические запреты**: См. [rules-complete.md#17-критические-запреты](./rules-complete.md#17--критические-запреты)

---

**Последнее обновление**: Август 2025
**Связанные файлы**:

- [rules-complete.md](./rules-complete.md) - Общие бизнес-правила
- [visual-design-rules.md](./visual-design-rules.md) - Визуальные правила