> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yume.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Комплекты (наборы)

> Объединение нескольких продуктов в единый продукт с собственным составом, ценообразованием и публикацией в витрине — модель данных, автоматика сохранения и расчёт доступности.

Полный перечень полей — в [глоссарии](/ru/logic/inventory/inventory-sets-glossary).

Комплект — это «набор», который объединяет несколько продуктов в единый продукт с собственным составом, отдельным ценообразованием и возможностью публикации в витрине. Клиент арендует комплект как одну позицию, а система рассчитывает, сколько таких наборов можно собрать из свободных единиц каждого входящего продукта.

## Модель данных

Раздел построен вокруг трёх сущностей: сам **Комплект**, его состав (**Позиции комплекта**) и ценовые варианты (**Цены комплекта**).

### Комплект

Карточка набора. Хранит общие атрибуты продукта, настройки ценообразования и признаки публикации.

| Поле                 | Тип                | Назначение                                                           |
| -------------------- | ------------------ | -------------------------------------------------------------------- |
| Название             | текст              | Наименование комплекта                                               |
| Артикул              | текст              | Пользовательский код (не проверяется на уникальность на уровне базы) |
| Изображение          | файл (изображение) | Фото комплекта; при сохранении из него создаётся миниатюра           |
| Количество           | целое число        | Справочное поле количества комплектов                                |
| Категория            | связь              | Категория каталога                                                   |
| Скидка               | связь              | Привязанная скидка                                                   |
| Период тарификации   | связь              | Базовый период времени для расчёта цены                              |
| Бонус                | число (2 знака)    | Бонусная сумма/начисление                                            |
| Цена                 | число (2 знака)    | Базовая цена комплекта                                               |
| Тип ценообразования  | перечисление       | Процентное или точное                                                |
| Доп. данные          | структура (JSON)   | Произвольные дополнительные атрибуты                                 |
| Комментарий          | текст              | Свободное примечание                                                 |
| Слаг (URL)           | текст              | Человекочитаемый идентификатор для витрины                           |
| Опубликован          | флаг               | Виден ли комплект в витрине                                          |
| Фиксированный состав | флаг               | Признак статичного (неизменяемого) набора                            |

<Info>
  Тип ценообразования задаёт способ расчёта итоговой стоимости: **процентное** (наценка или скидка в процентах относительно составляющих) либо **точное** (заданная фиксированная цена). По умолчанию используется процентное.
</Info>

### Позиция комплекта

Одна строка состава — какой продукт и в каком количестве входит в набор.

| Поле          | Тип              | Назначение                                     |
| ------------- | ---------------- | ---------------------------------------------- |
| Комплект      | связь            | Набор, которому принадлежит позиция            |
| Продукт       | связь            | Продукт, единицы которого входят в набор       |
| Количество    | целое число      | Сколько единиц продукта нужно на один комплект |
| Обязательная  | флаг             | Обязательна ли позиция в составе               |
| Альтернатива  | связь (на себя)  | Ссылка на альтернативную позицию               |
| Тарифная цена | число (2 знака)  | Цена позиции по тарифу                         |
| Фильтр        | структура (JSON) | Параметры подбора конкретных единиц            |

Позиции можно связывать в альтернативные группы: одна позиция ссылается на другую как на «альтернативу», а обратные ссылки образуют набор её заменителей. Это позволяет описывать взаимозаменяемые варианты внутри комплекта. Позиции всегда выстроены в порядке их создания.

### Цена комплекта

Ценовой вариант набора, привязанный к конкретному периоду тарификации, с порядком отображения и признаком публикации.

| Поле         | Тип             | Назначение                                       |
| ------------ | --------------- | ------------------------------------------------ |
| Комплект     | связь           | Набор, к которому относится цена                 |
| Название     | текст           | Название ценового варианта                       |
| Период       | связь           | Период тарификации для этой цены                 |
| Цена         | число (2 знака) | Стоимость за период                              |
| Опубликована | флаг            | Видна ли цена клиентам (по умолчанию — да)       |
| Порядок      | целое число     | Позиция в списке (пересчитывается автоматически) |

## Логика и побочные эффекты

### Сохранение комплекта: миниатюра и слаг

При каждом сохранении карточки выполняются два автоматических шага:

1. **Миниатюра изображения.** Если изображение поменялось и оно задано, вместо оригинала сохраняется уменьшенная миниатюра.
2. **Слаг для витрины.** Если изменилось название или слаг ещё не заполнен, он генерируется заново из названия (с суффиксом-меткой набора).

Слаг обязан быть уникальным в пределах одной компании. Если при сохранении возникает конфликт уникальности пары «компания + слаг», система не роняет запрос: слаг сбрасывается в пустое значение и сохранение повторяется без него.

<Warning>
  Из-за такого поведения комплект с конфликтующим слагом может сохраниться вообще без слага. Это влияет на его адресацию в витрине — человекочитаемая ссылка у него будет отсутствовать до следующего успешного пересчёта.
</Warning>

<Note>
  После любого сохранения или удаления комплекта запускается синхронизация витрины (обновление опубликованных продуктов). Именно поэтому изменения в наборе отражаются на публичной странице автоматически.
</Note>

### Автосдвиг порядка цен

Порядок отображения ценовых вариантов управляется автоматически. Сразу после сохранения очередной цены все прочие цены с таким же или бо́льшим значением порядка сдвигаются на одну позицию вниз (их порядок увеличивается на единицу). Так новая цена «вставляется» в список, не перезаписывая соседей.

<Warning>
  Сдвиг срабатывает при каждом сохранении, а не только при создании. Повторное сохранение уже существующей цены снова толкнёт вниз все записи с бо́льшим или равным порядком — значения порядка могут «расползаться». Порядок стоит трактовать как относительный признак сортировки, а не как стабильный номер строки.
</Warning>

### Удаление комплекта — мягкое

Удаление комплекта через интерфейс не стирает запись из базы. Вместо этого создаётся отметка о выведении из оборота с методом «удаление» и указанием, кто её создал. Комплект остаётся в системе (например, для истории и метрик), но помечается как удалённый.

<Info>
  В списках комплект приходит с вычисляемым признаком «удалён»: он выставляется, если для набора существует хоть одна отметка о выведении из оборота (независимо от её метода). Так фронтенд отличает мягко удалённые наборы от активных.
</Info>

## Как это используется

### Расчёт доступности комплекта

Ключевая величина для набора — сколько таких комплектов можно собрать и сколько из них свободно на заданный интервал времени. Логика опирается на состав.

Для каждой позиции набора считаются две величины по её продукту:

* **Всего единиц** — сколько единиц продукта вообще есть (не проданы, не приписаны к складу, не выведены из оборота, с учётом доступа пользователя к точкам проката).
* **Свободных единиц** — сколько единиц продукта свободно на выбранный интервал (по расписанию занятости), за вычетом единиц, явно исключённых из подбора.

Затем каждая величина делится на количество единиц этого продукта в комплекте (с защитой от деления на ноль — знаменатель не меньше единицы). Получается, сколько комплектов «обеспечивает» данная позиция.

<Tip>
  Итог по комплекту берётся по самой дефицитной позиции: доступное количество набора равно **минимуму** среди всех его позиций. Логика верна интуитивно — комплект нельзя собрать в большем числе, чем позволяет самая ограниченная составляющая.
</Tip>

Сводка по всем комплектам агрегирует эти минимумы: суммируются собираемые количества и свободные количества по всем наборам, отдельно считается число наборов и суммарный доход по комплектам (из метрик прибыли).

<Warning>
  Интервал доступности задаётся параметрами начала и конца. Если они не переданы, оба берутся равными текущему моменту — то есть по умолчанию доступность считается «на сейчас», а не на будущий период аренды. Для корректного резерва интервал нужно передавать явно.
</Warning>

<Note>
  Список состава и сводка используют слегка разные механизмы подсчёта свободных единиц: список состава опирается на общий расчёт доступности со статусом «свободна», а сводка и карточки наборов — на расписание занятости. Результаты близки, но при пограничных состояниях единиц могут расходиться на единицы.
</Note>

### Управление составом

Позиции комплекта редактируются в контексте конкретного набора: список позиций всегда фильтруется по идентификатору комплекта из адреса запроса, а при создании новой позиции комплект подставляется автоматически из того же адреса. Клиенту не нужно (и нельзя косвенно) переназначить позицию другому набору через это тело запроса. Каждая позиция в ответе обогащается данными своего продукта: название, артикул, изображение, категория, а также «всего» и «свободно» единиц.

### Управление ценами

Ценовые варианты также редактируются в рамках набора: список фильтруется по комплекту, при создании комплект подставляется автоматически. Список цен возвращается в порядке создания.

<Note>
  Актуальный редактор состава и цен работает с сокращённым набором полей (идентификатор, название, период, порядок для цен; количество, продукт, альтернатива, обязательность для позиций). Сама стоимость и тарифные привязки настраиваются отдельными операциями — массовым созданием и обновлением тарифов комплекта, а также отдельным списком тарифов набора.
</Note>

### Тарифы комплекта

Помимо простых ценовых вариантов у набора есть тарифы, связывающие его с периодами и ценовыми строками. Их можно получить списком по комплекту (только тарифы, привязанные к ценовой строке набора) и редактировать пакетно — массовым созданием и массовым обновлением. Это отдельный слой ценообразования поверх базовой цены и типа ценообразования комплекта.

## Особенности поведения

* Доступное количество комплектов берётся как **минимум** по всем позициям набора — лимитирует самая дефицитная составляющая, а не сумма или среднее.
* Список состава набора и сводка используют разные механизмы подсчёта свободных единиц (список состава — общий расчёт доступности со статусом «свободна»; сводка и карточки — расписание занятости), поэтому в пограничных случаях числа свободных единиц могут расходиться.
* При создании позиции или цены привязка к набору берётся из адреса запроса и подставляется принудительно — сменить её через тело запроса нельзя.
* Артикул комплекта не имеет ограничения уникальности на уровне базы — это обычное текстовое поле пользовательского кода.

<Info>
  При делении «всего/свободно» единиц на количество в позиции знаменатель принудительно берётся не меньше единицы — это защита от деления на ноль, когда в позиции указано нулевое количество. Порядок сортировки: позиции комплекта и цены в списках отдаются по времени создания, а не по полю «порядок».
</Info>

## Связанные страницы

<CardGroup cols={2}>
  <Card title="Глоссарий: Комплекты (наборы)" icon="book" href="/ru/logic/inventory/inventory-sets-glossary">
    Полный перечень полей комплекта, его позиций и ценовых вариантов.
  </Card>

  <Card title="Инвентарь и услуги (CRM)" icon="boxes-stacked" href="/ru/logic/inventory">
    Обзорная страница модуля инвентаря и услуг.
  </Card>

  <Card title="Инвентарь (единицы)" icon="box" href="/ru/logic/inventory/inventory-items">
    Отдельные единицы оборудования: статусы, пробег, страховка, импорт и перемещение.
  </Card>

  <Card title="Продукт" icon="layer-group" href="/ru/logic/inventory/inventory-groups">
    Учёт однотипного инвентаря по количеству вместо отдельных единиц.
  </Card>

  <Card title="Тарифы и цены" icon="tags" href="/ru/logic/inventory/tariffs">
    Тарифы аренды по временным периодам для единиц, продуктов и комплектов.
  </Card>

  <Card title="Доступность и расписание" icon="calendar-check" href="/ru/logic/inventory/availability">
    Расписание занятости инвентаря и расчёт доступности с учётом заказов.
  </Card>

  <Card title="Субаренда" icon="handshake" href="/ru/logic/inventory/sublease">
    Периоды субаренды единиц с процентом владельца — источник истории выручки.
  </Card>

  <Card title="Услуги (сервисы)" icon="concierge-bell" href="/ru/logic/inventory/services">
    Дополнительные платные услуги и их тарифы в каталоге и заказах.
  </Card>

  <Card title="Обслуживание и ремонт" icon="screwdriver-wrench" href="/ru/logic/inventory/maintenance">
    Плановое и разовое техобслуживание по интервалу или пробегу.
  </Card>

  <Card title="Инвентаризация" icon="clipboard-check" href="/ru/logic/inventory/inventorization">
    Проверки состояния инвентаря при выдаче и приёмке заказов.
  </Card>
</CardGroup>
