Остатки
Остаток живёт в таблице ms3remains_remains. В manager его правят в двух местах: на вкладке товара и в общем списке. На витрине точное значение отдаёт сниппет ms3Remains, а списки товаров обычно читают проекцию msProductData.stock.

Вкладка товара
Откройте товар MiniShop3. Вкладка Остатки показывает сетку комбинаций и текущие количества.

Строки собираются так:
- Базовая строка товара без опций. Подпись в API:
Base. - Варианты ms3Variants, если пакет установлен. Подпись: артикул (
sku). Если артикул пустой, показываетсяVariant #id. - Комбинации значений отслеживаемых опций. Значения берутся из заполненных опций товара (
msProductOption). Набор ключей задаётms3remains_option_keys. Комбинации — декартово произведение этих значений.
Если ms3remains_option_keys пуст, третья группа не строится. На вкладке остаются только базовая строка и варианты. Подробности про пустой список ключей: Системные настройки.
Сетка ограничена 200 комбинациями опций плюс базовая строка и варианты. Если у товара слишком много значений, часть сочетаний на вкладке не появится. Тогда задайте более узкий список ключей или правьте остаток через CSV.
Отслеживание и ноль
- ни одна строка ещё не сохранена (у всех
remain_idпустой) — товар не отслеживается и продаётся без ограничения. Вкладка показывает предупреждение об этом - ноль в уже сохранённой строке — нет в наличии. Такую комбинацию в корзину добавить нельзя
Пока вы не нажмёте Сохранить хотя бы у одной строки, товар остаётся неотслеживаемым, даже если в полях уже стоят числа.
Как править количество
В каждой строке есть текущее значение и поле ввода. Допускаются дробные числа до трёх знаков после запятой (DECIMAL(12,3)).
Над таблицей:
- Итого — сумма количеств по всем строкам сетки
- Комментарий — общий текст к сохранениям этой сессии. Попадает в события
ms3remainsOnBeforeRemainChange/ms3remainsOnAfterRemainChange - Заполнить пустые по умолчанию — появляется, если
ms3remains_remains_defaultбольше нуля. Подставляет это значение во все строки с количеством0и сразу сохраняет их - Сохранить — пишет все изменённые строки. На кнопке показывается число правок, например Сохранить (3). Если одна строка не записалась, цикл останавливается. Исправьте ошибку и сохраните оставшиеся
У каждой строки своя кнопка Сохранить. Она активна, только пока черновик отличается от записанного значения.
Без разрешения ms3remains_manage поля ввода скрыты, количества только читаются.
Раздел «Остатки»
Пункт меню компонента открывает общий список по всем товарам. Экран как у обычных разделов MODX 3: заголовок страницы снаружи, белая панель с вкладками Остатки и Настройки.

На панели списка:
- кнопка Изменить остаток открывает диалог новой записи
- счётчик Всего — число строк, попавших под фильтр
- фильтр Наличие: в наличии / нет в наличии
- поле Поиск по названию товара (Enter или кнопка Применить)
- Сбросить очищает поиск и наличие
- Экспорт CSV и Импорт CSV
Фильтра по категории в интерфейсе нет. Manager API принимает categoryId, но экран его не показывает.
Колонки таблицы: товар, SKU варианта, опции, количество, статус (В наличии / Нет в наличии), дата обновления, действие Изменить.
Пагинация как у гридов MODX: первая / предыдущая / номер страницы / следующая / последняя, выбор «на странице» 10, 20, 50, 100. По умолчанию 20 строк.
Если записей нет, экран предлагает импортировать CSV.
Диалог «Изменить остаток»

Для новой записи выберите товар и при необходимости вариант. Для строки из таблицы товар и вариант заблокированы: меняется только количество этой комбинации.
Поле количества принимает дробные значения до трёх знаков. Комментарий необязателен. Если его не заполнить, в событие уйдёт текст «Изменение остатка».
Создание новой комбинации опций из этого диалога не предусмотрено. Комбинации появляются на вкладке товара или через CSV, если строка уже есть (remain_id).
Формат CSV: Обмен с внешними системами.
Витрина: сниппет ms3Remains
Кратко: сниппет отдаёт число, текст наличия, JSON или остатки по значениям опций. Полная таблица параметров и примеры Fenom/MODX: сниппет ms3Remains.
{'!ms3Remains' | snippet}
{'!ms3Remains' | snippet : ['id' => 22]}[[!ms3Remains]]
[[!ms3Remains? &id=`22`]]Как считается результат:
- без опций в вызове — сумма остатков по всем строкам товара
- переданы все опции из
ms3remains_option_keys— остаток одной комбинации - переданы не все опции — сумма по подходящим комбинациям. Пример:
&color=красный`` при ключахcolor,sizeвернёт сумму по всем размерам красного &variant=27`` — остаток варианта ms3Variants с этим id
Если передан чужой вариант или опции не сходятся со строками остатка, сниппет вернёт 0, текст «Нет в наличии» или JSON с quantity: 0. Страница при этом не падает.
Включите ms3remains_hide_quantity, чтобы вместо числа получить «В наличии / Нет в наличии». Задайте ms3remains_moreless_count, например 10, чтобы остаток выше порога выводился словом «Много».
Рецепты
Некэшируемый вывод
Сниппет вызывайте некэшируемым ([[!ms3Remains]]), иначе страница из кэша покажет устаревший остаток. На страницах со списками товаров, где десятки некэшируемых вызовов дороги, выводите проекцию [[+stock]] из msProductData.stock (см. Проекцию), а точный остаток показывайте на карточке товара.
Скрыть опции с нулевым остатком
Один вызов на карточку возвращает остатки по каждому значению опций (цвет, размер и т.д.):
{'!ms3Remains' | snippet : ['id' => $id, 'return' => 'options']}[[!ms3Remains? &id=`[[+id]]` &return=`options`]]В JS или Fenom скройте значения с количеством 0. Так не нужно вызывать сниппет на каждое значение опции.
Блокировка кнопки «Купить»
При добавлении в корзину компонент сам вернёт ошибку, если комбинации нет на остатке. Чтобы убрать кнопку заранее, используйте тот же сниппет: при available = false выводите «Нет в наличии» вместо формы.
Каталог «только в наличии» через mFilter
Свой тип фильтра не нужен: mFilter читает проекцию msProductData.stock. Настройка фильтра, кнопка «Только в наличии» и ms3.refresh() после AJAX: mFilter.
