[msProductRemains] Компонент учёта остатков товара
Купить компонент msProductRemains возможно в магазине modStore.pro. 
msProductRemains — компонент, предназначенный и реализующий учёт количества оставшихся единиц товара. Остатки могут формироваться по нескольким свойствам (полям товара miniShop2).
При редактировании товара вам необходимо выставить количество оставшихся товаров по каждой комбинации свойств, указанных в настройках компонента.
После того, как статус заказа будет равен тому статусу, что указан в настройках компонента, количество оставшихся товаров, заказанных клиентом, будет автоматически уменьшено на то количество, что было в корзине клиента.
2. Зайдите в настройки системы, выберите фильтр «msproductremains» и настройте параметры для нужд своего сайта.

3. Откройте страницу редактирования товара, заполните значения в свойствах товара, которые указаны в настройках компонента, сохраните товар и перезагрузите страницу.

4. Перейдите на вкладку «Остатки», обновите таблицу и отредактируйте остатки.

На этом настройка компонента завершена. Документация по компоненту также доступна на сайте docs.modx.pro.

msProductRemains — компонент, предназначенный и реализующий учёт количества оставшихся единиц товара. Остатки могут формироваться по нескольким свойствам (полям товара miniShop2).
При редактировании товара вам необходимо выставить количество оставшихся товаров по каждой комбинации свойств, указанных в настройках компонента.
После того, как статус заказа будет равен тому статусу, что указан в настройках компонента, количество оставшихся товаров, заказанных клиентом, будет автоматически уменьшено на то количество, что было в корзине клиента.
Настройка компонента
1. Купите компонент msProductRemains и установите его через менеджер пакетов.2. Зайдите в настройки системы, выберите фильтр «msproductremains» и настройте параметры для нужд своего сайта.

3. Откройте страницу редактирования товара, заполните значения в свойствах товара, которые указаны в настройках компонента, сохраните товар и перезагрузите страницу.

4. Перейдите на вкладку «Остатки», обновите таблицу и отредактируйте остатки.

На этом настройка компонента завершена. Документация по компоненту также доступна на сайте docs.modx.pro.
Комментарии: 179
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Андрей1. Перед добавлением товара в корзину проверяется, есть ли он в таком количестве в наличии, если нет, добавления в корзину не происходит.
2. Перед подтверждением заказа проводится точно такая же проверка.
3. При переводе заказа в статус отменен, товар возвращается в остатки (опционально).
Это что первое пришло в голову…
Кроме этого добавлена единая страница, на которой можно просмотреть остатки товаров (а не открывать товары по отдельности, чтобы смотреть остатки).
Плагин снова отправлен в магазин, надеюсь на этот раз его добавят вовремя.
Если вам нужно редактирование всех остатков на одной странице можете оплатить работу (2 тр.) и я добавлю этот функционал.
Можно одним запросом из таблицы modx_ms2_order_products собрать статистику по одному варианту, а возможно, и всю сразу.
Если это так необходимо, я добавлю на единую страницу с остатками возможность вывода количества проданных вариантов в новой версии плагина.
1. Возможно ли использовать ваше дополнением в паре со «Скрипт импорта в miniShop2 из CSV»? Если да, то пытаюсь понять какие поля fields указывать в строке запуска импорта.
2. Вашего дополнения нет на Тестовом тарифе хостинга modhost. Добавите?
2. Я с удовольствием добавлю, только знать бы как это сделать.
2. Василий ответил, что Так, что это значит его инициатива, наверное. :(
Это пример для размеров. Соответственно, должны быть в свойствах Размеры указаны Размер 1, Размер 2 и Размер 3.
а в CSV файле в строке:
И про само поле в настройках: msproductremainns_option
что будет, если через некоторое время сменить, уже указанное поле на новое. Допустим решили продавать товар, у него разные вкусы, а размер один.
В строке импорта пишем:
а в CSV файле в строке пишем:
Визуально, все остатки обнулятся, придётся их заполнять заново. Поле указывается общее для всех товаров. По факту, в базе ничего не перезапишется (то есть останутся данные остатков по размерам), пока не будет пересохранён каждый товар с данными остатков по вкусам.
то же самое в карточке товара?
Такой вариант вызова сниппета выведет все размеры товара, которые есть в наличии (то есть скроет все размеры, которые не в наличии).
А есть ещё такой вариант обработки этой ситуации.
Вызываем сниппет так:
И в чанке tpl.msOptions.row выводим параметр таким образом:
Тогда сниппет выведет все размеры, но размеры не в наличии будут неактивными (выбрать их нельзя будет, но они будут видны).
Спасибо большое за советы и само дополнение.
Надо переварить, насколько актуально для текущего проекта (новые товары рано или поздно появятся)
Но для сайтов «не супермаркет» то. что надо.
Но что-то у меня не так. Версия 1.0.7-pl. У товаров свойств нет, все разные, вес не учитывается… Остаток на странице товара ввожу. В «Настройки системы» свойство товара, на основании которого будут формироваться остатки пробовал оставлять size (хотя у меня повторюсь нет) пробовал оставлять пустое поле. Результат одинаков — в админке «Управление остатками товаров» таблица с товарами вообще пустая… ни товаров ни остатков… вообще ни чего.
А так-то работает, на странице товара (на сайте) пишет сколько его осталось.
Что это может быть? Куда глянуть?
Всё работает, список выводится, остатки из таблицы меняются.
Можете показать настройки компонента?
Собственно у меня отключены к показу поля color,size,weight на вкладке товара. Попробую вернуть (хотя использовать их не буду) и опять выставлю в настройках size. Отпишусь.
Еще раз спасибо! Удачи!
Не из всех категорий в общую таблицу остатков выводит товар. В нижней части таблицы плагин честно пишет: «Показано 1-6 из 8», «Страницы 1 из 1» т.е. пролистать не куда… Куда он ещё 2 припрятал, которые показывать не хочет :) Ограничений фильтрами не делаю.
Так что может быть и так: «Показано 1-5 из 2». ;)
Методом «случайного щелканья» обнаружил. что сортировка в таблице работает прикольно. Выбираю «товар» — показывает 8 товаров из 11 (три потерял), выбираю «цена» — показывает 9 товаров причем 2 новых (которые раньше потерял) + 1 которого не было, а два старых пропали, но всего потерял теперь два старых товара :)))
Может там что-то с сортировкой?
А что значит «товары указаные в таблице, возможно, для них остатки никогда не сохранялись.» Это какое-то особое действие? Собственно делаю так:
1. Создать товар-> пишу имя-> Сохранить.
2. Страница обновляется и теперь ввожу описание, цену, артикул, остатки.-> Сохранить
и дальше смотрю таблицу «остатки»
«Пока» это обнадеживает =). А когда планируется добавление такой возможности?
Об автоматизации: Когда товаров несколько сотен, у каждого по 10 и более комбинаций и все летят из 1С… да, лучше автоматизировать =D
А с mSklad будет работать?
modstore.pro/cabinet/tickets/ticket
Прошу подсказать, что я делаю не так:
Пытаюсь прописать условие, при котором товар с остатком «0» выдавал бы на своей страничке «Нет в наличии», вместо «Добавить в корзину». Однако ничего не выходит.
Я вызвал сниппет:
И прописал условие:
Но мне в любом случае выдается «Нет в наличии». Если в условии ставить не пустое значение, а null также не работает. Если вызвать плейсхолдер +remains, то он отображает корректное количество товара.
Что я упускаю?
Я пробовал аналогичное, но с «ge» :)
Сейчас скопировал ваш код, все равно не сработало (как и ранее).
Как я понял, теоретически я делаю все правильно и проблема только в «сопротивлении системы»? Тогда буду думать, что может мешать… или где запятые пропустил… Если решу, отпишусь. :)
Работает вот так:
И здесь главное — "!"… Ранее не подумал, что для плейсхолдера внутри одной странички это важно, потому как я чистил кеш почти каждый раз перед обновлением, не сообразил, что это может влиять так сильно). Но это логично, теперь уже не забуду.
IS тоже работает, если проверять на пустое значение.
Спасибо за помощь, я хоть все лишнее отсечь смог.
Спустя несколько лет у меня вновь возникли проблемы с выводом кнопки «нет в наличии» в данном компоненте.
Несмотря на "!" в вызовах сниппета и плейсхолдера, при первой загрузке страницы из 12 товаров, каждому товару присваивается количество первого в списке. Если страничку перезагрузить, то все работает корректно.
Как такое может быть? Могу ли без принудительного обновления страницы я добиться верных значений?
Подскажите пожалуйста как передать значение остатков в другой сниппет на уровне php?
Цель — автоматизировать выставление значения наличия (true/false) для yml-выгрузки.
К тому же, сниппет с недавних пор выдаёт все остатки товара в виде JSON массива. Для этого вызвать надо сниппет так:
В итоге получаем массив в виде:
И далее ищите в массиве нужные данные.
Есть ещё вариант подключить компонент как сервис и использовать функцию getRemains, но она не возвращает JSON-массив.
Надеюсь, я вам помог. Желаю удачи!
$q = $modx->newQuery('msProduct', array('published' => 1, 'deleted' => 0, 'class_key' => 'msProduct'));
$q->innerJoin('msProductData', 'Data', '`msProduct`.`id` = `Data`.`id`');
$q->select('`msProduct`.`id`,`parent`,`pagetitle`,`longtitle`,`description`,`introtext`');
$q->select('`Data`.`price`, `Data`.`image`'.$delivery);
$q->select('`Data`.`price`, `Data`.`image`'.$delivery);
$q->sortby('pagetitle','asc');
$q->innerJoin('msProductRemains', '`Remains.remains', '`msProduct`.`id` = `Remains.product`.`id`');
получаю ошибку
Could not load class: msProductRemains from mysql.msproductremains.
как правильно вызвать класс msProductRemains?
Could not load class: msprRemains from mysql.msprremains.
newQuery('msProduct', array('published' => 1, 'deleted' => 0, 'class_key' => 'msProduct'));
offer id=v[id] available=«true»
соответственно true для остатков больше 0 false для всего остального.
Или вот так:
Или просто подключите сервис. Он подтянет все нужные классы за собой.
Подскажите по такому вопросу.
Клиент сделал заказ — со склада товар списался.
Менеджер изменил заказ через админку (например по просьбе клиента).
Как автоматически вернуть на склад исключенный из заказа товар?
Возможно, автоматически у вас плагин не активируется в нужных событиях.
Нужно установить галочку на срабатывание плагина компонента на события:
И всё должно заработать.
а как быть со свойствами товаров, добавленными через плагины minishop2? оно не выводится в таблицу, к сожалению
Можно ли сделать в этом компоненте так, что бы была возможность добавить в корзину и оформить заказ с отсутствующим на остатках товаром?
При этом в магазине появлялась бы надпись «под заказ» в момент покупки последней позиции.
Вот думаю, что можно реализовать «под заказ» через «число остатков для сравнения». Если вместо «нет на складе». Написать «под заказ».
Не пойму только как вывести эти слова. Подскажите, пожалуйста
Сергей, спасибо за сниппет!
[[!getRemains:gt=`0`:then=`[[%mspr_text_more]]`:else=`[[%mspr_text_zero]]`]]
Далее по плану с фильтром разбираться. Компонент с msearch2 дружит? Чтоб фильтровать «в наличии»/«под заказ»
вылез очень серьезный и глупый баг, связанный с тем, что данные хранятся json строкой.
кейс: используются color,size
остатки импортированы из таблицы.
размеры у кроссовок, например: 34, 34.5, 35, 35.5
в таблице экселя 34 это число, а 34.5 — строка. Так это и пишется в базу — «size»:34 и «size»:«34.5»
а дальше начинается жесть, потому что размер 34 (и все целые числа) не добавить в корзину, хотя остатки есть!
лезу в плагин — вижу метод getRemains
лезу в класс — и в этом методе вижу ПРЯМОЕ СРАВНЕНИЕ JSON строки, сформированной тут же, со строкой из базы!
я понимаю, что как иначе выбрать из базы, но выходит реализация в корне неверная: в скрипте массив собирается из данных post-запроса, а там всё — строки. И в итоге мы пытаемся сравнить «size»:«34» из скрипта с «size»:34 из базы. А поскольку это строка, и ей плевать на сами данные, получаем ошибку.
а если вдруг окажется, что свойства в остатке записаны не в том порядке, что в системной настройке, опять же будет ошибка, хотя данные совпадут.
в связи с этим предлагаю изменить метод getRemains — получать там сначала всю коллекцию остатков данного товара, а потом циклом проходить по ней с приведением типов, а не тупо сравнивать строку. Дольше, зато работать будет.
Если вы хотите сами внести изменения, то можете поправить строку 73 в файле msproductremains.class.php, вставив такой код:
Я более тщательно проверю работу данного решения и выложу обновление в ближайшие несколько дней.
Сергей2. Как храниться все это дело в БД? Смогу ли я выгрузить в 1С остатки адекватно, т.е. товар с определенной опцией как отдельный товар?
2. Остатки хранятся в отдельной таблице, опции заносятся в виде json массива, в котором опции упорядочиваются в том же порядке, как указаны они в настройке.
СергейСергейmsListOrders — недоступны, YaCassa — недоступна, msExtraFields — недоступны))
СергейСергейСергейДва скрина — список со остатками и карта товара.
pr.allser68.beget.tech/strange-row.png
pr.allser68.beget.tech/strange-row-2.png
А вот почему появляется эта строка, то скорее всего вы действуете так. Может вы сначала сохраняете товар, потом добавляете свойства, снова сохраняете? Тогда это вполне возможно. При первом сохранении без свойств создается общая запись об остатков для товара. А когда добавляете свойства и снова сохраняете товар, создаются уже остатки для указанных свойств.
Если указывать свойства перед первым сохранением товара, то общей записи не будет появляться.
СергейСергейСергейСергей[[!getRemains:toPlaceholder=`remains`? id=`[[+id]]`]]
[[+remains:lt=`1`:then=`нет`:else=`[[+remains]] шт.`]]
Постоянно выдается первый вариант «Нет».
Списко товаров вызывается при помощи сниппета mfilter2. Если добавляю в него такую конструкцию
'leftJoin' => [
'Remains' => [
'class' => 'msprRemains',
'on' => 'msProduct.id = Remains.product_id AND Remains.remains > 0'
]
],
'groupby' => 'msProduct.id',
'select' => [
'msProduct' => '*',
'Remains' => 'SUM(Remains.remains) as remains'
],
То остатки выводятся правильно, но перестает работать сортировка. При нажатии на сортировку все товары исчезают. Не подскажете в чем может быть причина. Заранее спасибо!
Вот полностью вызов сниппета
{'!mFilter2' | snippet: [
'paginator' => 'pdoPage',
'element' => 'msProducts',
'class' => 'msProduct',
'parents'=>$modx->resource->id,
'depth' => 10,
'filters'=> 'ms|price:number'
'tplFilter.outer.default'=>'mfilter-slider.tpl'
'tplFilter.row.default'=>'mfilter-number.tpl'
'tpl' => 'category-product.tpl',
'tplOuter' => 'mFilter2-outer.tpl',
'leftJoin' => [
'Remains' => [
'class' => 'msprRemains',
'on' => 'msProduct.id = Remains.product_id AND Remains.remains > 0'
]
],
'groupby' => 'msProduct.id',
'select' => [
'msProduct' => '*',
'Remains' => 'SUM(Remains.remains) as remains'
],
'limit' => 18,
'maxLimit' => 200,
'pageLimit' => 12,
'tplPage' => '@INLINE {$pageNo}',
'tplPageActive' => '@INLINE {$pageNo}',
'tplPageWrapper' => '@INLINE {$pages}',
'tplPagePrev' => '@INLINE <',
'tplPageNext' => '@INLINE >',
'tplPageSkip' => '@INLINE ...</span',
'tplPagePrevEmpty' => '@INLINE <<',
'tplPageNextEmpty' => '@INLINE >>',
'sortby' => '{«menuindex»:«ASC»}',
'where' => '{«template»:«4»}'
]}
Тогда фильтрация будет работать корректно.
И подскажите, как мне удобнее организовать работу с остатками, если у меня у товара нету опций как таковых (размер, цвет). Думал изначально, что у товара будет просто одно дополнительное циферное поле, а получается, что мне надо вводить какую-нибудь опцию типа Цвет — «Обычный», потом добавлять в таблицу с остатками одну строку с нужным числом. Ну и для импорта дополнительные сложности, если его вообще запилят.
Из настроек компонента удалить все поля, по которым ведутся остатки (то есть оставить значение настройки пустым). И даже если этого не сделать, без всяких опций всё равно должны появится одна строка с нужным числом в таблице. Я постарался ясно изложить как пользоваться компонентом в документации.
Если у вас появились какие-то проблемы с компонентом, пишите в техподдержку компонента в магазине modStore.pro. Я решу все проблемы с компонентом
где
проверяются остатки.
Как мне правильно подставить туда чтобы подставлялись остатки по id продукта на форуме читал вы отвечали ну что то у меня не получается
modx.pro/components/5022#comment-81789
А вместо пишем Данный случай присоединения таблицы откидывает опции (а в вашем случае они не нужны) и записи с остатками меньше 0. И в remains записывается суммарный остаток товара по всем опциям.
В вашем случае на один товар должна быть одна запись с остатками, поэтому можно было просто обойтись более простым присоединением таблицы:
Но и первый вариант тоже должен корректно работать. В общем, пробуйте. Должно работать.
У меня такой вопрос, как при выборе цвета обновлять информацию о наличии данного цвета?
Мой вызов:
[[!getRemains:toPlaceholder=`remains` ?&id=`[[*id]]`]]
[[!+remains:gte=`1`:then=`В наличии`:else=`Нет в наличии`]]
Лучше использовать словари, потому как после запроса берутся фразы из словаря. Если у вас вместо слова появляется цифра с остатком, то необходимо включить опцию «Скрывать количество остатков» в настройках компонента.
Вопрос следующий, нужно зафиксировать определенное количество товара, т.е. допустим, первый товар остаток 0 (и его нельзя добавить в корзину), а второй товар остаток 9999999(при добавлении любого количества товара должно остаться 9999999).
С такими настройками если 0, то не добавляется, если 9999999 добавляется и вычитается.
далее нужно вызвать в &filters=``
Автор очень долго отвечает на тикет, подскажите если есть у кого такая-же проблема. Когда из 1с вычитается товар в 0, то компонент почему то оставляет 1. Хотя в логах написано, что mSync передает 0. А в msProductRemains остается 1. Если товар не заканчивается, то нормально вычитает.
Вывожу так, но потом сам фильтр не ищет, пишет результатов нет
Тогда будет искать после загрузки
можете подсказать правильно ли все там?
да прописывал 'loadModels' => 'msproductremains' — не помогает
Пропала вкладка «Остатки» и новые товары так же не отображаются в сводной таблице остатков. Дополнение не дорабатывали и никаким образом
miniShop2 — 2.5.0-pl
msProductRemains — 2.1.25-pl
DevTools failed to load SourceMap: Could not load content for lovebythemoon.store/manager/assets/modext/modx.jsgrps-min.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
Total parse time 18.2190938 s
Total queries 365
Total queries time 17.4899082 s
Если отключить,
Total parse time 1.6309950 s
Как то можно ускорить работу?
Что-то я пока на этапе планирования не могу склеить в голове как красивее реализовать, да потом еще с 1С -7 связать :)
1. Для вывода товара на сайте используется компонент msFilter2.
2. Для отслеживания остатков компонент msProductRemains
2. В карточках товара важно указывать возможность «Купить» или статус «Нет в наличии». Для чего используется конструкция:
Вызов сниппета, в каждой карточке (в чанке msProducts.row):
И условие:
Условие срабатывает прекрасно, если просто зайти на страницу каталога.
Однако, на странице выдается 20 товаров из множества, таким образом есть еще и пагинация. Если переключаться через пагинацию, то условие выше не работает, потому что в каждую карточку загружается значение первой карточки. Если обновить страничку, то все считается корректно.
Я так понимаю, что здесь мешает сам фильтр. Может быть кто-то встречался с такой проблемой и решил ее?
Остатки без характеристик.
Из комментариев пробовал так
properties
{«msproductremains»:{«remains»:«49»}}
{«msproductremains»:{«49»}}
{«msproductremains»:«49»}
49
remains
49
Не выходит
А можно ли, используя ваше дополнение, изменять товарные остатки и загружать их из таблицы CSV при помощи компонента msImportExport?
Т.е. можем мы для товарных остатков завести специальное поле в виде опции Minishop2, которую «увидит» msImportExport?
Или если для остатков ваш компонент вводит собственное уникальное поле — можно ли сделать так, чтобы остатки импортировались/экспортировались в таблицу при помощи msImportExport?
Опции в товаре выводу так (в чанке):
И чанк tpl-msOptions:
Хочу уточнить: для товаров без свойств и модификаций Ваш компонент будет работать?
Could not generate encryption key
Vehicle 04b9f528f736384b46f7132420614ef0 in transport msproductremains-2.1.28-pl failed to install and indicated the process should be aborted.
Невозможно установить пакет с подписью: msproductremains-2.1.28-pl
Но пробовал на основном домене, при установленном пакете, сделать заказ — вылетает ошибка и заказ не проходит /core/components/gallery/elements/tv/output/
в системных настройках
mspr_active_bcstatus
Нет
2026-02-17, 9:58 am
Проверка до добавления в корзину
mspr_active_before_add
Нет
2026-02-17, 9:47 am
Проверка до сохранения заказа
mspr_active_before_order
Нет