[msProductRemains] Компонент учёта остатков товара

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

При редактировании товара вам необходимо выставить количество оставшихся товаров по каждой комбинации свойств, указанных в настройках компонента.

После того, как статус заказа будет равен тому статусу, что указан в настройках компонента, количество оставшихся товаров, заказанных клиентом, будет автоматически уменьшено на то количество, что было в корзине клиента.

Настройка компонента

1. Купите компонент msProductRemains и установите его через менеджер пакетов.

2. Зайдите в настройки системы, выберите фильтр «msproductremains» и настройте параметры для нужд своего сайта.


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



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



На этом настройка компонента завершена. Документация по компоненту также доступна на сайте docs.modx.pro.
Сергей Фещуков
13 марта 2015, 10:47
5
5 696
+5

Комментарии: 124

Сергей Скат
13 марта 2015, 18:23
+1
не поверишь, только что пришла задача которую как рас решает плагин, го покупать
Денис Богдановский
14 марта 2015, 10:57
+1
Долго новостей не было и тут сразу такое! При первой необходимости куплю.
Сергей Фещуков
15 марта 2015, 08:57
+1
В версии 1.0.0-beta содержится ошибка, из-за которой в админке не появляются поля для ввода остатков. Слишком поторопился выложить её. В магазин уже направлена версия 1.0.1-beta с исправлением ошибки. 1.0.2-beta уже готова, но её не тороплюсь выложить, чтобы более тщательно проверить всё.
Андрей
16 марта 2015, 13:09
0
Кому нужно бесплатно и без изысков, можете юзать такой плагин modx.pro/help/3950/ — самый первый код.
Алексей
16 апреля 2015, 01:12
0
Не увидел плагин, начал готовить остатки на migx, сразу подумал о поле, в котором показывается, сколько уже такого варианта продано. Здесь не вижу такого. Вроде бы логично. Если указываете количество, почему сразу статистику не вести, чтобы можно было вывести её в красивом виде, оценить популярностьвариантов и скорректировать закупку
    Алексей
    16 апреля 2015, 01:36
    0
    Ожидаю от такого компонента следующий функционал:
    1. Перед добавлением товара в корзину проверяется, есть ли он в таком количестве в наличии, если нет, добавления в корзину не происходит.
    2. Перед подтверждением заказа проводится точно такая же проверка.
    3. При переводе заказа в статус отменен, товар возвращается в остатки (опционально).

    Это что первое пришло в голову…
      Сергей Фещуков
      16 апреля 2015, 05:22
      0
      Пожелания 1 и 2 работают в 1.0.3-beta, пожелание 3 уже реализовано в 1.0.4-beta, но она почему-то в магазин до сих пор не попала. Сегодня снова отправлю заявку на добавление новой версии плагина.

      Кроме этого добавлена единая страница, на которой можно просмотреть остатки товаров (а не открывать товары по отдельности, чтобы смотреть остатки).
        Сергей Фещуков
        16 апреля 2015, 05:44
        0
        Прошу прощения, проверка товаров перед изменением статуса заказа добавлена в 1.0.4-beta.
        Плагин снова отправлен в магазин, надеюсь на этот раз его добавят вовремя.
        Алексей
        16 апреля 2015, 10:11
        0
        Единая страница с остатками — это здорово. А изменять все остатки на одной странице нельзя?
          Сергей Фещуков
          16 апреля 2015, 17:52
          0
          К сожалению, пока нет, но в будущем такая возможность появится.
            Алексей
            16 апреля 2015, 17:59
            0
            Было бы здорово
              Володя
              16 апреля 2015, 18:07
              0
              остатки есть в modstore.pro/packages/ecommerce/msoptionsprice2

              Если вам нужно редактирование всех остатков на одной странице можете оплатить работу (2 тр.) и я добавлю этот функционал.
                Алексей
                16 апреля 2015, 18:13
                0
                Пока достаточно имеющегося. Если я правильно понял, все дополнения отсюда привязываются к домену. Когда буду переносить сайт с технического домена на основной, проблем не возникнет?
                  Сергей Фещуков
                  16 апреля 2015, 18:15
                  +1
                  Один раз можно сбросить хост самому, с помощью кнопки в личном кабинете. Последующие через службу поддержки.
    Сергей Фещуков
    16 апреля 2015, 05:34
    0
    Зачем свою статистику выдумывать, если всё уже ведёт сам miniShop2.

    Можно одним запросом из таблицы modx_ms2_order_products собрать статистику по одному варианту, а возможно, и всю сразу.

    Если это так необходимо, я добавлю на единую страницу с остатками возможность вывода количества проданных вариантов в новой версии плагина.
      Алексей
      16 апреля 2015, 10:09
      0
      Извиняюсь. Вы правы, сведения о продажах должны анализироваться на основе заказов. К остаткам они не имеют никакого отношения.
Игорь Улькин
26 июня 2015, 16:52
0
Сергей, два вопроса.

1. Возможно ли использовать ваше дополнением в паре со «Скрипт импорта в miniShop2 из CSV»? Если да, то пытаюсь понять какие поля fields указывать в строке запуска импорта.
&fields=article,pagetitle,tv1,size,size,gallery,gallery,tv3
2. Вашего дополнения нет на Тестовом тарифе хостинга modhost. Добавите?
    Сергей Фещуков
    26 июня 2015, 17:03
    0
    1. Информация об остатках хранится в стандартном поле properties. Поэтому это поле добавлять надо. Только надо отметить, что в этом поле могут быть и другие параметры. Пример как выглядит значение этого поля дам чуть позже, пока не за компьютером.
    2. Я с удовольствием добавлю, только знать бы как это сделать.
Игорь Улькин
26 июня 2015, 17:35
0
1. спасибо. жду с нетерпением.
2. Василий ответил, что
всё вручную, и не всё еще может нормально само устанавливаться — нужно тестировать.
Так, что это значит его инициатива, наверное. :(
    Сергей Фещуков
    28 июня 2015, 08:17
    0
    Вид поля properties с остатками такой
    {"msproductremains":{"Размер 1":"49","Размер 2":"55","Размер 3":"12"}}
    Это пример для размеров. Соответственно, должны быть в свойствах Размеры указаны Размер 1, Размер 2 и Размер 3.
      Игорь Улькин
      29 июня 2015, 12:54
      0
      то есть в строке импорта пишем:
      &fields=article,size;size;size;properties,properties,properties...
      а в CSV файле в строке:
      артикул 1;Размер 1;Размер 2;Размер 3;Размер 1:49;Размер 2:55;Размер 3:12

      И про само поле в настройках: msproductremainns_option
      что будет, если через некоторое время сменить, уже указанное поле на новое. Допустим решили продавать товар, у него разные вкусы, а размер один.
        Сергей Фещуков
        29 июня 2015, 14:08
        +1
        К сожалению, скорее всего всё сложнее. Придётся добавлять поле properties как оно есть, то есть делать следующим образом.
        В строке импорта пишем:
        &fields=article,size,size,size,properties
        а в CSV файле в строке пишем:
        артикул 1;Размер 1;Размер 2;Размер 3;{"msproductremains":{"Размер 1":"49","Размер 2":"55","Размер 3":"12"}}

        Визуально, все остатки обнулятся, придётся их заполнять заново. Поле указывается общее для всех товаров. По факту, в базе ничего не перезапишется (то есть останутся данные остатков по размерам), пока не будет пересохранён каждый товар с данными остатков по вкусам.
      Игорь Улькин
      29 июня 2015, 13:38
      0
      и как указать фильтр вывода в msProducts если какого-то размера нет? (в каталоге чтобы эти размеры были неактивными)
      то же самое в карточке товара?
        Сергей Фещуков
        29 июня 2015, 14:16
        +1
        Можно использовать сниппет
        [[!msOptionsWithRemains?&id=`[[+id]]`&name=`size`]]
        Такой вариант вызова сниппета выведет все размеры товара, которые есть в наличии (то есть скроет все размеры, которые не в наличии).

        А есть ещё такой вариант обработки этой ситуации.
        Вызываем сниппет так:
        [[!msOptionsWithRemains?&id=`[[+id]]`&name=`size`&showMissing=`1`]]
        И в чанке tpl.msOptions.row выводим параметр таким образом:
        <option value="[[+value]]" [[+selected]] [[+remains:lte=`0`:then=`disabled="disabled"`]]>[[+value]]</option>
        Тогда сниппет выведет все размеры, но размеры не в наличии будут неактивными (выбрать их нельзя будет, но они будут видны).
          Игорь Улькин
          29 июня 2015, 14:23
          0
          Фуф, все узнал, что волновало.

          Спасибо большое за советы и само дополнение.
          Надо переварить, насколько актуально для текущего проекта (новые товары рано или поздно появятся)
          Но для сайтов «не супермаркет» то. что надо.
plazma
04 сентября 2015, 23:38
0
Хороший компонент!
Но что-то у меня не так. Версия 1.0.7-pl. У товаров свойств нет, все разные, вес не учитывается… Остаток на странице товара ввожу. В «Настройки системы» свойство товара, на основании которого будут формироваться остатки пробовал оставлять size (хотя у меня повторюсь нет) пробовал оставлять пустое поле. Результат одинаков — в админке «Управление остатками товаров» таблица с товарами вообще пустая… ни товаров ни остатков… вообще ни чего.
А так-то работает, на странице товара (на сайте) пишет сколько его осталось.
Что это может быть? Куда глянуть?
    Сергей Фещуков
    05 сентября 2015, 16:12
    +1
    Видимо где-то ошибка при получении списка. Если нажать кнопку обновить под таблицей, слово Загрузка исчезает или остаётся?
      plazma
      05 сентября 2015, 16:19
      0
      Спасибо за ответ! Слово «Загрузка» появляется на секунду и исчезает. Поведение похожее на поиск списка и его отсутствие.
        Сергей Фещуков
        05 сентября 2015, 16:33
        +1
        Попробую сам установить чистый modx, minishop2 и поставить с нуля компонент и проверить что там. И отпишусь о решении проблемы.
          plazma
          05 сентября 2015, 17:09
          0
          Большое спасибо! Как будто getlist.class.php не создает getlist. Файлы в процессоре присутствуют все.
    Сергей Фещуков
    07 сентября 2015, 11:07
    0
    Установил компонент с нуля на чистом modx 2.4.0 + minishop2 2.2.0-pl2, настройки никакие у него не менял, то есть формируются остатки по опции size, столбцы таблицы на странице остатков стандартные:
    id,pagetitle,color,size,price,weight,article,published,instock,remains
    Всё работает, список выводится, остатки из таблицы меняются.

    Можете показать настройки компонента?
      plazma
      07 сентября 2015, 11:45
      0
      Спасибо! Да я уверен, что всё должно работать и косяк на моей стороне. А как показать настройки компонента — скриншотом? Я их менял только в выборе опции по которой должны формироваться остатки ставил size и убирал его совсем… без разницы.
      Собственно у меня отключены к показу поля color,size,weight на вкладке товара. Попробую вернуть (хотя использовать их не буду) и опять выставлю в настройках size. Отпишусь.
plazma
07 сентября 2015, 20:40
0
Собственно прошу прощенья, как и думал мой косяк был. Снес все товары и начал их заносить при уже подключенном плагине. Все заработало как нужно, опций у товаров нет, выбор опции по которой должны формироваться остатки ставил size. Плагин отлично работает и выполняет все заявленные функции.
Еще раз спасибо! Удачи!
plazma
07 сентября 2015, 21:43
0
Другая напасть :(
Не из всех категорий в общую таблицу остатков выводит товар. В нижней части таблицы плагин честно пишет: «Показано 1-6 из 8», «Страницы 1 из 1» т.е. пролистать не куда… Куда он ещё 2 припрятал, которые показывать не хочет :) Ограничений фильтрами не делаю.
    Сергей Фещуков
    08 сентября 2015, 07:33
    0
    Я не совсем корректно сделал эту таблицу (но другого варианта не нашёл) и для реализации деления товаров по опциям сделал обработку полученных массивов, добавляя новые товары с отрицательным ID. Поэтому эти данные сейчас некорректно отображаются, им доверять нельзя. Но если у вас действительно не все товары указаны в таблице, возможно, для них остатки никогда не сохранялись.
    Так что может быть и так: «Показано 1-5 из 2». ;)
      plazma
      08 сентября 2015, 14:48
      0
      :) Я понял…
      Методом «случайного щелканья» обнаружил. что сортировка в таблице работает прикольно. Выбираю «товар» — показывает 8 товаров из 11 (три потерял), выбираю «цена» — показывает 9 товаров причем 2 новых (которые раньше потерял) + 1 которого не было, а два старых пропали, но всего потерял теперь два старых товара :)))
      Может там что-то с сортировкой?
      А что значит «товары указаные в таблице, возможно, для них остатки никогда не сохранялись.» Это какое-то особое действие? Собственно делаю так:
      1. Создать товар-> пишу имя-> Сохранить.
      2. Страница обновляется и теперь ввожу описание, цену, артикул, остатки.-> Сохранить
      и дальше смотрю таблицу «остатки»
shiyankin
04 декабря 2015, 01:14
0
Скажите пожалуйста, можно как-нибудь реализовать, что у некоторых товаров может быть количество, а некоторые могут быть бесконечные, то есть не иметь количества.
    Сергей Фещуков
    04 декабря 2015, 04:22
    0
    Задать максимально возможное количество остатков для данного товара, например, 999999999. Тогда можно о них забыть. Но такой специальной возможности в компоненте не имеется.
Анна
21 января 2016, 14:41
0
Скажите, пожалуйста, а по дополнительным свойствам (помимо цвета и размера, например, «кол-во разъемов») ведется учет?
    Сергей Фещуков
    21 января 2016, 14:45
    0
    Если честно, я не пробовал. В теории, если дополнительное свойство существует и по типу аналогично цвету или размеру, то должно работать. Но учёт ведётся максимум по двум свойствам пока.
      Анна
      21 января 2016, 14:53
      0
      А… ну вот… а мне по трем нужно.
      «Пока» это обнадеживает =). А когда планируется добавление такой возможности?
        Сергей Фещуков
        21 января 2016, 15:04
        +1
        Думаю в ближайшую неделю добавлю. Функционал поддерживает хоть сколько свойств. Основная проблема найти результат произведения N массивов для создания всевозможных комбинаций свойств. Можно конечно пойти другим путём и добавить окно для создания комбинаций вручную. Но лучше автоматизировать этот момент.
          Анна
          21 января 2016, 15:31
          0
          Спасибо. В ближайшую неделю это очень кстати! Сижу, жду тогда)
          Об автоматизации: Когда товаров несколько сотен, у каждого по 10 и более комбинаций и все летят из 1С… да, лучше автоматизировать =D
          А с mSklad будет работать?
            Сергей Фещуков
            21 января 2016, 18:03
            0
            У меня нет данного компонента, чтобы протестировать. Поэтому ничего не могу сказать по этому поводу.
            Сергей Фещуков
            21 января 2016, 19:34
            0
            Пробуйте. Добавил в магазин версию 2.0.7-pl с необходимыми доработками. Удачно пришло в голову решение указанной выше задачи. :) Всё проверил, должно работать без проблем. Если найдете ошибки, обязательно сообщите мне в техподдержку.
            modstore.pro/cabinet/tickets/ticket
Viacheslav
13 июля 2016, 12:36
0
Здравствуйте! Подскажите, пожалуйста, будет ли работать из коробки вместе msOptionsPrice2 modstore.pro/packages/ecommerce/msoptionsprice2?
    Сергей Фещуков
    13 июля 2016, 12:42
    0
    Здравствуйте. Как данный компонент должен работать с msOptionsPrice2? Или вы про то, не будет ли конфликта? Не могу точно утверждать, но не должно быть каких-либо конфликтов.
      Viacheslav
      13 июля 2016, 12:52
      0
      Интересует, будут ли переключаться цены, которые прописаны в msOptionsPrice2 по опциям и работать ваши остатки?
        Сергей Фещуков
        13 июля 2016, 13:03
        0
        Да, должно всё работать. Если будут какие-то проблемы, то можете всегда написать мне в техподдержку в магазине modstore.pro.
Сергей Самусев
23 декабря 2016, 15:30
0
Не меняет текст на блоке с товаром, хотя настройки включены на текст, а не числовое количество.



    Сергей Фещуков
    24 декабря 2016, 18:48
    0
    Данная опция работает на странице конкретного товара, когда остатки подгружаются AJAX запросом. Как вы вызываете сниппет?
      Сергей Самусев
      25 декабря 2016, 19:41
      0
      [[!getRemains:default=`Под заказ`?
              &id=[[+id]]
          ]]
      в чанке tpl.msProducts.row
Валерий
12 марта 2017, 11:35
0
Добрый день.

Прошу подсказать, что я делаю не так:
Пытаюсь прописать условие, при котором товар с остатком «0» выдавал бы на своей страничке «Нет в наличии», вместо «Добавить в корзину». Однако ничего не выходит.

Я вызвал сниппет:
[[!getRemains:toPlaceholder=`remains`? &id=[[+id]]]]
И прописал условие:
[[+remains:is=``:then=`<span class="no-remains">Нет в наличии</span>`:else=`<button class="btn btn-default" type="submit" name="ms2_action" value="cart/add"><i class="glyphicon glyphicon-barcode"></i> В корзину</button>`]]
Но мне в любом случае выдается «Нет в наличии». Если в условии ставить не пустое значение, а null также не работает. Если вызвать плейсхолдер +remains, то он отображает корректное количество товара.

Что я упускаю?
    Сергей Фещуков
    12 марта 2017, 11:42
    0
    Попробуйте вот так
    [[+remains:lt=`1`:then=`<span class="no-remains">Нет в наличии</span>`:else=`<button class="btn btn-default" type="submit" name="ms2_action" value="cart/add"><i class="glyphicon glyphicon-barcode"></i> В корзину</button>`]]
      Валерий
      12 марта 2017, 11:45
      0
      Не сработало. В любом случае срабатывает первое условие.
      Я пробовал аналогичное, но с «ge» :)
        Сергей Фещуков
        12 марта 2017, 11:47
        0
        Я, надеюсь, вы плейсхолдер ставите после вызова сниппета?
          Валерий
          12 марта 2017, 11:47
          0
          Да :)
            Сергей Фещуков
            12 марта 2017, 11:49
            0
            На странице товара сниппет нужно вызвать так
            [[!getRemains:toPlaceholder=`remains`]]
              Валерий
              12 марта 2017, 11:51
              0
              Так тоже пробовал. ID добавил уже после.
              Сейчас скопировал ваш код, все равно не сработало (как и ранее).

              Как я понял, теоретически я делаю все правильно и проблема только в «сопротивлении системы»? Тогда буду думать, что может мешать… или где запятые пропустил… Если решу, отпишусь. :)
                Сергей Фещуков
                12 марта 2017, 12:59
                0
                Тогда попробуйте явно задать ID:
                [[!getRemains:toPlaceholder=`remains` ?&id=`[[*id]]`]]
                  Валерий
                  12 марта 2017, 13:23
                  0
                  Этот вариант не сработал, но я нашел решение.

                  Работает вот так:
                  [[!+remains:gte=`1`:then=`<button class="btn btn-default" type="submit" name="ms2_action" value="cart/add"><i class="glyphicon glyphicon-barcode"></i> В корзину</button>`:else=`<span class="no-remains">Нет в наличии</span>`]]
                  И здесь главное — "!"… Ранее не подумал, что для плейсхолдера внутри одной странички это важно, потому как я чистил кеш почти каждый раз перед обновлением, не сообразил, что это может влиять так сильно). Но это логично, теперь уже не забуду.
                  IS тоже работает, если проверять на пустое значение.

                  Спасибо за помощь, я хоть все лишнее отсечь смог.
      Валерий
      12 марта 2017, 11:47
      0
      Вероятно, это не столь существенно. Но на страничке с списком товаров условие составить получилось. По вашему примеру на docs.modx.pro. Когда нужно !msProducts? добавить &leftJoin и &select
Илья
02 июня 2017, 12:54
0
Здравствуйте.

Подскажите пожалуйста как передать значение остатков в другой сниппет на уровне php?

Цель — автоматизировать выставление значения наличия (true/false) для yml-выгрузки.
    Сергей Фещуков
    02 июня 2017, 13:20
    0
    Добрый день. Можно просто вызвать сниппет getRemains из вашего сниппета.
    $remains = $modx->runSnippet('getRemains', array(
    	'product_id' => 123,
    	'color' => 'Красный',
    	'size' => 'Большой'
    ));
    К тому же, сниппет с недавних пор выдаёт все остатки товара в виде JSON массива. Для этого вызвать надо сниппет так:
    $remains = $modx->runSnippet('getRemains', array(
    	'product_id' => 123,
    	'return' => 'json'
    ));
    $remains = $modx->fromJSON($remains);
    В итоге получаем массив в виде:
    $remains = array (
      0 => array (
        'options' => 
        array (
          'color' => 'Красный',
          'size' => 'Малый',
        ),
        'remains' => 6,
      ),
      1 => array (
        'options' => 
        array (
          'color' => 'Синий',
          'size' => 'Большой',
        ),
        'remains' => 9,
      )
    )
    И далее ищите в массиве нужные данные.
    Есть ещё вариант подключить компонент как сервис и использовать функцию getRemains, но она не возвращает JSON-массив.
    $msProductRemains = $modx->getService('msProductRemains');
    $remains = $msProductRemains->getRemains(array(
    	'product_id' => 123,
    	'color' => 'Красный',
    	'size' => 'Большой'
    ));
    Надеюсь, я вам помог. Желаю удачи!
      Илья
      02 июня 2017, 13:31
      0
      А как внедрить его в такой код?

      $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?
        Сергей Фещуков
        02 июня 2017, 13:34
        0
        Попробуйте так:
        $q->innerJoin('msprRemains', 'Remains', '`msProduct`.`id` = `Remains`.`product_id`');
          Илья
          02 июня 2017, 13:34
          0
          пробовал — выдаёт
          Could not load class: msprRemains from mysql.msprremains.
          Илья
          02 июня 2017, 13:36
          0
          думаю вопрос в вызове в классе msproduct
          newQuery('msProduct', array('published' => 1, 'deleted' => 0, 'class_key' => 'msProduct'));
          Илья
          02 июня 2017, 13:37
          0
          фактически мне нужно в переменную считать остатки конкретного товара, найденного по msProduct.id
        Илья
        02 июня 2017, 13:34
        0
        по сути мне нужно сравнение с 0 для этой строчки
        offer id=v[id] available=«true»
        соответственно true для остатков больше 0 false для всего остального.
          Сергей Фещуков
          02 июня 2017, 13:39
          0
          Тогда перед этим делом добавьте вот такое:
          $modx->loadClass('msprRemains', MODX_CORE_PATH.'/components/msproductremains/model/msproductremains/');
          Или вот так:
          $modx->loadClass('msprRemains', MODX_CORE_PATH.'/components/msproductremains/model/');
          Или просто подключите сервис. Он подтянет все нужные классы за собой.
          $msProductRemains = $modx->getService('msProductRemains');
            Илья
            02 июня 2017, 13:49
            0
            Спасибо огромное! первый вариант помог!
Илья
07 июня 2017, 17:37
0
Еще раз здравствуйте коллеги.

Подскажите по такому вопросу.

Клиент сделал заказ — со склада товар списался.

Менеджер изменил заказ через админку (например по просьбе клиента).

Как автоматически вернуть на склад исключенный из заказа товар?
    Сергей Фещуков
    09 июня 2017, 21:05
    0
    В minishop2 версии 2.4.10-pl добавили нужные события, чтобы заработала эта функция. github.com/bezumkin/miniShop2/commit/000be7961edd6b04469edf262cb0cbb0bc4c9934
    Возможно, автоматически у вас плагин не активируется в нужных событиях.
    Нужно установить галочку на срабатывание плагина компонента на события:
    msOnBeforeCreateOrderProduct
    msOnCreateOrderProduct,
    msOnBeforeUpdateOrderProduct,
    msOnUpdateOrderProduct,
    msOnBeforeRemoveOrderProduct,
    msOnRemoveOrderProduct
    И всё должно заработать.
Алексей Бгатов
19 июня 2017, 17:30
0
Здравствуйте!
а как быть со свойствами товаров, добавленными через плагины minishop2? оно не выводится в таблицу, к сожалению
    Сергей Фещуков
    19 июня 2017, 17:36
    0
    Добрый день. На странице товара проблем не должно быть, а вот на странице остатков могут быть проблемы. Пока я не нашёл решения этой проблемы.
      Алексей Бгатов
      19 июня 2017, 17:40
      0
      не, у меня и там и там не показывает. При этом в шаблоне я вполне вменяемо работаю с остатками
Виктор
28 июня 2017, 23:54
0
Приветствую, коллеги!

Можно ли сделать в этом компоненте так, что бы была возможность добавить в корзину и оформить заказ с отсутствующим на остатках товаром?
При этом в магазине появлялась бы надпись «под заказ» в момент покупки последней позиции.
    Сергей Фещуков
    29 июня 2017, 05:38
    0
    Добрый день. Отключить возможность проверки остатков перед добавлением товара в корзину и перед оформлением заказа (изменением статуса заказа) можно отключить в настройках компонента. Но при этом в магазине не будет появляться надпись «под заказ», это надо будет вам самим доработать, с помощью плагина.
      Виктор
      29 июня 2017, 10:24
      0
      Спасибо за ответ! Я вообще поубирал все проверки. Заказы работают, остаток уменьшается! В минус уходит, если нет товара — тоже хорошо, наглядно :)

      Вот думаю, что можно реализовать «под заказ» через «число остатков для сравнения». Если вместо «нет на складе». Написать «под заказ».

      Не пойму только как вывести эти слова. Подскажите, пожалуйста
        Виктор
        29 июня 2017, 11:21
        0
        Все, отбой! Нашел)
        Сергей, спасибо за сниппет!

        [[!getRemains:gt=`0`:then=`[[%mspr_text_more]]`:else=`[[%mspr_text_zero]]`]]

        Далее по плану с фильтром разбираться. Компонент с msearch2 дружит? Чтоб фильтровать «в наличии»/«под заказ»
          Сергей Фещуков
          30 июня 2017, 12:49
          0
          К сожалению, на сегодняшний день связка с mSearch2 мною не была реализована. Мне как-то задавали вопрос на эту тему, но решения. насколько я помню, пока не было
            Виктор
            07 июля 2017, 21:19
            0
            Понятно. Нашел только этот вывод msProducts. Вроде столько параметров. Под фильтр их все равно так просто не вставить?

            [[!msProducts?
              &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"}`
              &where=`{"Remains.remains:>":"0"}`
            ]]
Андрей
12 июля 2017, 16:38
0
Здравствуйте. Возможен ли импорт остатков через компонент msImportExport?
    Сергей Фещуков
    15 июля 2017, 12:10
    0
    Добрый день. В новой версии убрали поддержку моего компонента. Я веду переговоры по поводу возможности возврата поддержки моего компонента или введения нового функционала, который позволит мне самому реализовать эту поддержку. Но пока результатов нет.
    Алексей Бгатов
    27 июля 2017, 16:54
    0
    если у Вас уже был до этого msimportexport с импортом остатков, то он будет работать и в новой версии. Проверял
Ольга
24 июля 2017, 12:05
0
Добрый день. Подскажите, в фильтрах mSearch2 можно фильтровать по вашим остаткам? Например, я ставлю фильтр по sizes и меня интересует, чтобы там были только те размеры у которых остаток больше 0.
Алексей Бгатов
27 июля 2017, 16:51
0
Здравствуйте, Сергей!

вылез очень серьезный и глупый баг, связанный с тем, что данные хранятся json строкой.
кейс: используются color,size
остатки импортированы из таблицы.
размеры у кроссовок, например: 34, 34.5, 35, 35.5
в таблице экселя 34 это число, а 34.5 — строка. Так это и пишется в базу — «size»:34 и «size»:«34.5»
а дальше начинается жесть, потому что размер 34 (и все целые числа) не добавить в корзину, хотя остатки есть!
лезу в плагин — вижу метод getRemains
лезу в класс — и в этом методе вижу ПРЯМОЕ СРАВНЕНИЕ JSON строки, сформированной тут же, со строкой из базы!
$rem = $this->modx->getObject('msprRemains', array(
	'product_id' => $product_id
	,'options' => $this->modx->toJSON($where)
));
я понимаю, что как иначе выбрать из базы, но выходит реализация в корне неверная: в скрипте массив собирается из данных post-запроса, а там всё — строки. И в итоге мы пытаемся сравнить «size»:«34» из скрипта с «size»:34 из базы. А поскольку это строка, и ей плевать на сами данные, получаем ошибку.

а если вдруг окажется, что свойства в остатке записаны не в том порядке, что в системной настройке, опять же будет ошибка, хотя данные совпадут.

в связи с этим предлагаю изменить метод getRemains — получать там сначала всю коллекцию остатков данного товара, а потом циклом проходить по ней с приведением типов, а не тупо сравнивать строку. Дольше, зато работать будет.
    Алексей Бгатов
    27 июля 2017, 17:44
    0
    $raw = $this->modx->getCollection('msprRemains', array('product_id' => $product_id));
    			
    $rem = false;
    foreach ($raw as $one) {
    	$compare = $one->get('options');
    	if ($where == $compare) {
    		$rem = $one;
    		break;
    	}
    }
    вот так вот у меня заработало. Нестрогое сравнение массивов плюет на тип значений и порядок ключей, что меня полностью устраивает)
      Сергей Фещуков
      31 июля 2017, 13:30
      0
      Добрый день, Алексей. Спасибо за вашу наводку. Я внимательно прочитал ваш комментарий и просмотрел работу моего компонента и miniShop2. И пришёл к некоторому другому решению. Перебор массива данных и так ведётся внутри функции getRemains, поэтому я просто добавил условие для проверки является ли введённое значение опции целочисленным значением или дробным значением/строкой.
      Если вы хотите сами внести изменения, то можете поправить строку 73 в файле msproductremains.class.php, вставив такой код:
      if ( !empty($tmp) ) $where[trim($option)] = ctype_digit($tmp) ? intval($tmp) : $tmp;
      Я более тщательно проверю работу данного решения и выложу обновление в ближайшие несколько дней.
        Алексей Бгатов
        31 июля 2017, 19:37
        0
        здравствуйте, Сергей! мое решение продиктовано желанием уйти полностью от сравнения json строки к сравнению фактичкских данных. Ваше опять возвращает к строкам. И оно чревато неточностями там, где перепутан порядок опций в строке или число сохранено как строка… воть
Сергей
04 августа 2017, 17:58
0
1. Можно будет сменить домен?
2. Как храниться все это дело в БД? Смогу ли я выгрузить в 1С остатки адекватно, т.е. товар с определенной опцией как отдельный товар?
    Сергей Фещуков
    05 августа 2017, 17:30
    0
    1. Один раз домен можно сбросить. Далее только через тех поддержку.
    2. Остатки хранятся в отдельной таблице, опции заносятся в виде json массива, в котором опции упорядочиваются в том же порядке, как указаны они в настройке.
Сергей
04 августа 2017, 20:40
0
админку можно щупануть?
    Андрей
    04 августа 2017, 23:36
    0
    Все дополнения из магазина доступны для установки на тестовом тарифе modhost.
Сергей
04 августа 2017, 23:50
0
да, защупал, клевая вещь! кстати, не ВСЕ дополнения из магазина доступны на тестовом, увы и ах)))
msListOrders — недоступны, YaCassa — недоступна, msExtraFields — недоступны))
Сергей
05 августа 2017, 16:49
0
Уточните, плиз, после установки модуля купить из категории нельзя, пишет «Выберите размер». Ничего не пиленное, все с нуля. (У товара опция — размеры, можно выбрать на странице товара, ясно-понятно, что в категории размер не выбрать, но все же)
    Сергей Фещуков
    05 августа 2017, 17:34
    +1
    Если вы смотрите из категории товаров, и у вас там нет выбора размера, то будет такая ошибка. Это связано с тем, что по умолчанию включена настройка проверки опций перед добавлением товара. Если у товара есть возможность выбора размера, то компонент будет требовать, чтобы этот размер был выбран, чтобы корректно учитывать остатки. Можно отключить эту настройку, но тогда не гарантируется правильный учёт остатков.
      Сергей
      07 августа 2017, 15:38
      0
      В принципе да, логика правильная. Заметил на некоторых ms2-сайтах, где есть размеры и видимо нет Вашего модуля — там при покупке из категории в корзину добавляется товар без размера, при покупке из карты товара — отдельной строкой с размером...)) Нонсенс будет для бухгалтерии…
Сергей
07 августа 2017, 20:36
0
А ни у кого такого не было — вместе со строками для каждой опции создается странная строка в списке остатков — в ней все размеры в строчку через запятую и для неё тоже можно вбить количество? Эта строка создается сразу при создании товара, собсно, вместе и с правильными строками остатков для каждой опции.
Два скрина — список со остатками и карта товара.
pr.allser68.beget.tech/strange-row.png
pr.allser68.beget.tech/strange-row-2.png
    Сергей Фещуков
    08 августа 2017, 07:39
    +1
    Это ошибка в отображении этой строки на общей странице остатков. В этой строке нет свойств, соответственно, в поле Размер должно быть указано Нет. Алгоритм компонента работает правильно, но в отображении строки ошибка. Я её поправлю в ближайшее время и выложу обновление.
    А вот почему появляется эта строка, то скорее всего вы действуете так. Может вы сначала сохраняете товар, потом добавляете свойства, снова сохраняете? Тогда это вполне возможно. При первом сохранении без свойств создается общая запись об остатков для товара. А когда добавляете свойства и снова сохраняете товар, создаются уже остатки для указанных свойств.
    Если указывать свойства перед первым сохранением товара, то общей записи не будет появляться.
      Сергей
      08 августа 2017, 09:57
      0
      Угу, спасибо достойный ответ. Так и есть — именно так добавляем товары. И ждем обновку.
      Сергей
      24 августа 2017, 11:20
      0
      После обновки также добавляет эту пустую строку.
        Сергей Фещуков
        24 августа 2017, 13:35
        0
        Если вы сохраняете товар без свойств изначально, то это правильное поведение компонента.
Станислав
16 августа 2017, 10:22
0
Здравствуйте! В версии minishop 2.4.6 данное дополнение не работает: просто не появляется дополнительная категория «Остатки» в карточке товара… Сначала я грешил на свой магазин, но на тестовом домене была та же беда.
    Сергей Фещуков
    16 августа 2017, 10:26
    0
    Добрый день. Спасибо за ваше замечание. Я обязательно посмотрю в чем проблема и выложу обновление
      Станислав
      16 августа 2017, 10:31
      0
      Про тестовый домен я погорячился, там всё нормально работает. Проблема у меня.
Сергей
09 сентября 2017, 20:49
0
Драсти!!)) А как можно дошлифовать Ваш компонент, чтобы он вбивал по умолчанию какие-то остатки товара, например, каждого размера по 100шт, а не ноль? У моих товаров до 15 опции РАЗМЕР и в каждом товаре приходится 15 раз вписывать кол-во товара
    Сергей Фещуков
    09 сентября 2017, 20:52
    +1
    Добрый день. В настройках компонента есть опция «Количество остатков по умолчанию». Она выполняет необходимую вам функцию.
      Сергей
      09 сентября 2017, 21:07
      -1
      Мда, мне точно пора за линзами!!)) Спасибо! Еще одно подтверждение тому, что и компонент отлично просчитан и автор хорош и отзывчив!!!
Алексей
16 января 2018, 20:50
1
0
Добрый вечер! На странице списка товаров вызываю снипет так
[[!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»}'
]}
    Сергей Фещуков
    28 сентября 2018, 21:11
    0
    В вызов mFilter2 необходимо добавить параметр:
    'loadModels' => 'msproductremains'
    Тогда фильтрация будет работать корректно.
Алексей
23 января 2018, 09:25
0
Добрый день! Не подскажете как выгружать из 1с (куплен компонент msync), количество товаров в поле остатков?
Александр
11 апреля 2018, 09:53
0
Подскажите, пожалуйста, может ли данный модуль менять статус товара на «Нет в наличии», если его количество становится равно нулю?
Алексей Андреев
15 июня 2018, 16:59
0
А по какой причине нету поддержки msimportexport? Это надо их разработчика напрягать или здешнего?

И подскажите, как мне удобнее организовать работу с остатками, если у меня у товара нету опций как таковых (размер, цвет). Думал изначально, что у товара будет просто одно дополнительное циферное поле, а получается, что мне надо вводить какую-нибудь опцию типа Цвет — «Обычный», потом добавлять в таблицу с остатками одну строку с нужным числом. Ну и для импорта дополнительные сложности, если его вообще запилят.
    Сергей Фещуков
    15 июня 2018, 17:41
    0
    А по какой причине нету поддержки msimportexport? Это надо их разработчика напрягать или здешнего?
    К сожалению, это не от меня и моего компонента зависит.

    И подскажите, как мне удобнее организовать работу с остатками, если у меня у товара нету опций как таковых (размер, цвет).
    Из настроек компонента удалить все поля, по которым ведутся остатки (то есть оставить значение настройки пустым). И даже если этого не сделать, без всяких опций всё равно должны появится одна строка с нужным числом в таблице. Я постарался ясно изложить как пользоваться компонентом в документации.

    Если у вас появились какие-то проблемы с компонентом, пишите в техподдержку компонента в магазине modStore.pro. Я решу все проблемы с компонентом
eflit
28 сентября 2018, 19:51
0
Здравствуйте, возник вопрос в подключении класса на сайте реализованы остатки с помощью вашего компонента без привязки к свойствам все работает отлично и есть вот такой код
public function get()
    {
        $list = [];
        $q = $this->modx->newQuery('modResource');
        $q->leftJoin('msProductData', 'Data', ['modResource.id = Data.id']);
        $q->leftJoin('msVendor', 'Vendor', ['Data.vendor = Vendor.id']);
        $q->innerJoin('msInformUserArrival', 'Arrival', ['modResource.id = Arrival.res_id']);
        $q->innerJoin('msInformUserMailing', 'Mailing', ['Arrival.mailing_index = Mailing.index']);
        $q->select($this->modx->getSelectColumns('modResource', 'modResource', 'product.'));
        $q->select($this->modx->getSelectColumns('msProductData', 'Data', 'product.'));
        $q->select($this->modx->getSelectColumns('msVendor', 'Vendor', 'product.vendor.'));
        $q->select($this->modx->getSelectColumns('msInformUserArrival', 'Arrival', 'arrival_'));
        $q->select($this->modx->getSelectColumns('msInformUserMailing', 'Mailing', 'mailing_'));
        $q->where([
            'published' => 1,
            'deleted' => 0,
            'iu_count:>' => 0,
            'Arrival.status:IN' => [1, 3],
            'Mailing.active' => 1,
        ]);
//        if (!$this->msInformUser->useCron) {
            $q->limit($this->config['limitSend']);
//        }
        if ($q->prepare() && $q->stmt->execute()) {
            while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
                $list[] = $row;
            }
        }
//        $this->modx->cacheManager->set('iustockout', $list, 7200);

        if (!empty($list)) {
            $this->prepareSending($list);
        }
        return true;
    }


где
'iu_count:>' => 0,
проверяются остатки.
Как мне правильно подставить туда чтобы подставлялись остатки по id продукта на форуме читал вы отвечали ну что то у меня не получается
modx.pro/components/5022#comment-81789
    Сергей Фещуков
    28 сентября 2018, 21:05
    +1
    Здесь иная ситуация, вам необходимо в запросе добавить таблицу с остатками и проверять остатки
    $q->leftJoin('msprRemains', 'Remains', ['modResource.id = Remains.product_id', 'Remains.remains > 0']);
    $q->select(['SUM(Remains.remains) as remains']);
    А вместо
    'iu_count:>' => 0,
    пишем
    'Remains.remains:>' => 0,
    Данный случай присоединения таблицы откидывает опции (а в вашем случае они не нужны) и записи с остатками меньше 0. И в remains записывается суммарный остаток товара по всем опциям.
    В вашем случае на один товар должна быть одна запись с остатками, поэтому можно было просто обойтись более простым присоединением таблицы:
    $q->leftJoin('msprRemains', 'Remains', ['modResource.id = Remains.product_id']);
    $q->select($this->modx->getSelectColumns('msprRemains', 'Remains'));
    Но и первый вариант тоже должен корректно работать. В общем, пробуйте. Должно работать.
      eflit
      28 сентября 2018, 22:12
      0
      Спасибо добавил вторым вариантом все корректно работает.
Айдар
10 октября 2018, 10:29
0



У меня такой вопрос, как при выборе цвета обновлять информацию о наличии данного цвета?

Мой вызов:
[[!getRemains:toPlaceholder=`remains` ?&id=`[[*id]]`]]
[[!+remains:gte=`1`:then=`В наличии`:else=`Нет в наличии`]]
    Сергей Фещуков
    11 октября 2018, 08:05
    0
    Оберните фразу с наличием в тег div с классом mspr-remains. И должен быть подключен стандартный JS-файл компонента (по умолчанию, он включен). Подробнее об этом здесь.
    [[!getRemains:toPlaceholder=`remains` ?&id=`[[*id]]`]]
    <div class="mspr-remains">[[!+remains=`0`:then=`[[%mspr_text_more]]`:else=`[[%mspr_text_zero]]`]]</div>
    Лучше использовать словари, потому как после запроса берутся фразы из словаря. Если у вас вместо слова появляется цифра с остатком, то необходимо включить опцию «Скрывать количество остатков» в настройках компонента.
      Айдар
      19 октября 2018, 13:37
      0
      Ваш вариант не помог, пришлось свой сниппет писать на основании Вашего…

      Вопрос следующий, нужно зафиксировать определенное количество товара, т.е. допустим, первый товар остаток 0 (и его нельзя добавить в корзину), а второй товар остаток 9999999(при добавлении любого количества товара должно остаться 9999999).



      С такими настройками если 0, то не добавляется, если 9999999 добавляется и вычитается.
eflit
17 октября 2018, 14:47
0
Здравствуйте подскажите пожалуйста как правильно вызвать в mFilter2 добавил в вызов сниппета
&leftJoin=`{ "Remains":{ "class":"msprRemains","on":"msProduct.id = Remains.product_id" } }`
    &select=`{ "msProduct":"*","Remains":"SUM(Remains.remains) as remains" }`
    &loadModels=`msproductremains`

далее нужно вызвать в &filters=``