msProductKits - удобное управление товарами-комплектами (наборами товаров)

Всем привет!

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

Пара сценариев, чтобы было понятно, для чего можно использовать:

1. Магазин шин и дисков.
В магазине продаются шины, колесные диски, их можно купить по одной штуке.
А еще мы хотим продавать промо-набор, куда входят: шины 4 шт, диски 4 шт, пакеты для хранения шин 4 шт и сертификат на шиномонтаж. При этом пакеты и сертификат отдельно купить нельзя, таких товаров на сайте нет.

2. Магазин производителя акустики.
Производитель выпускает несколько видов колонок, которые вполне себе можно купить по отдельности.
Но еще есть готовый набор, куда входят: 4 двухполосные акустические системы, центральный канал, сабвуфер и усилитель мощности. Этот набор можно купить целиком, на сайте он представлен отдельным товаром, причем его цена ниже, чем если покупать все отдельно. При этом усилитель отдельно не продается, это вообще сторонний усилитель, не этого производителя, он предлагается по партнерской программе.

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

Административная часть

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

Для примера я использую демонстрационный каталог (магазин шин/дисков) со следующей структурой:


У товара появилась новая вкладка, где можно добавить позиции комплекта:


Каждая строка — это товар, являющийся частью комплекта. Товар может быть как ссылкой на существующий товар (msProduct), так и мы можем просто написать его название. Так же можно указать некоторые дополнительные сведения (описание, количество, артикул, производителя).



У товара, который при этом является частью комплекта, в этой вкладке отображаются все комплекты, в состав которых он входит.



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

Фронтэнд
На сайте можно вывести информацию при помощи сниппета msProductKits.

Параметры сниппета msProductKits:
  • resource — id товара, по-умолчанию текущий ресурс;
  • mode — режим работы сниппета, может принимать 2 значения: owner (делаем выборку товаров, которые входят в комплект) или product (делаем выборку тех товаров, в которые входит наш товар как часть комплекта). В режиме product имеет смысл либо делать join таблицы ресурсов, либо получать только id Товаров для последующего вывода их с помощью msProducts;
  • tpl — шаблон отображения одной строки;
  • sortby, sortdir — сортировка;
  • tplWrapper, wrapIfEmpty, outputSeparator, toPlaceholder, toSeparatePlaceholders — давно всем известные параметры;
  • ids — укажите 1, чтобы сниппет вернул только id ресурсов вместо полных данных.

Выводим товары, входящие в Комплект:


Выводим все комплекты, в состав которых входит товар:


Послесловие
В принципе компонент небольшой, и его функционал при желании можно реализовать и через MIGX, но это будет не так удобно и презентабельно.
Если есть предложения и идеи по развитию — пишете в комментариях.

Компонент доступен в ModStore: modstore.pro/packages/ecommerce/msproductkits
Наумов Алексей
Наумов Алексей
21 декабря 2020, 10:08
modx.pro
3 648
Реклама

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

Алексей Шумаев
21 декабря 2020, 11:37
В чанк на фронте можно сразу добавить инфу о стоимости по отдельности и выгоде покупателя в комплекте.
Пользователям будет проще. Т.е. по отдельности сумма 35000, ваша выгода — 5000р, ~15%
    Роман
    Роман Старожил
    21 декабря 2020, 11:44
    Интересное решение. По шинам и дискам видал разные решения. У кого-то стоит кол-ве сразу 4 шт., у кого-то добавляются 4 шт. в корзину, а потом из корзины можно поменять кол-во. Сам буквально недавно реализовывал подобное решение, только для составных товаров.
      Spirit_Ninja
      Spirit_Ninja Старожил
      24 декабря 2020, 16:29
      Только недавно об этом думал! Очень полезно, спасибо.
        Наумов Алексей
        Наумов Алексей Администратор
        24 декабря 2020, 16:37
        Осталось дождаться модерации =)
          Spirit_Ninja
          Spirit_Ninja Старожил
          24 декабря 2020, 17:15
          Ждем)
        R2m0x94 (Vasily)
        R2m0x94 (Vasily) Старожил
        30 декабря 2020, 00:59
        Алексей, Спасибо. Тоже делал такой функционал, но только через тв. перечислял id дополнительных, но тут почувствовал гибкость исполнения. Только поставил и смотрю чанк. Предлагаю заменить на такой
        {var $item_name = $product | resource : 'pagetitle'}
        <tr>
            <td style="width: 40%;">
                {if $product > 0}
                <strong><a href="{$product | url}">{$item_name}</a></strong>
                {else}
                <strong>{$name}</strong>
                {/if}
            </td>
            <td style="width: 50%;"><small>{$description}</small></td>
            <td style="width: 10%; text-align: center;">
                <small>{$count} шт.</small>
            </td>
        </tr>
          Наумов Алексей
          Наумов Алексей Администратор
          30 декабря 2020, 09:35
          Я так понимаю, что речь идет о том, чтобы показать комплекты, в которые входит товар?
          Здесь история в том, что по идее нужно вызывать msProducts, который отобразит товары так, как нужно (с подключением изображений, параметров и т.д.).
          Я для этих случаев просто получал ids товаров, а после передавал их в msProducts:
          {set $ids = $_modx->runSnippet('!msProductKits', ['mode' => 'product','ids' => 1])}
          {if $ids}
          {'!msProducts' | snippet : [
              'parents' => 0,
              'resources' => $ids,
              'limit' => 0,
          ]}
          {/if}
          R2m0x94 (Vasily)
          R2m0x94 (Vasily) Старожил
          30 декабря 2020, 01:16
          Но при добавлении к товару, когда после перейти в пакет msProductKits, там пусто :'( печалька…
            Наумов Алексей
            Наумов Алексей Администратор
            30 декабря 2020, 09:35
            Про это не понял…
              R2m0x94 (Vasily)
              R2m0x94 (Vasily) Старожил
              10 июня 2021, 14:44
              Т.е сначала вызываю msProducts
              &where=`{ "id:IN":[{$_modx->resource['dopid']}]}`

              Далее
              {'!msProductKits' | snippet : [
                  'tplWrapper' => 'outerTpl',
                  'mode' => 'owner',
                  'tpl' => 'tpl.msProductKits.Item2',
                  'sortby' => 'id',
                  'sortdir' => 'asc',
              ]}
              Хороший компонент. Спасибо :)
            Владимир
            Владимир Старожил
            25 февраля 2021, 15:34
            Добрый день, Алексей.
            Почему-то не срабатывает сниппет в плагине на событие OnDocFormSave:
            $modx->runSnippet('!msProductKits', ['resource' => $id, 'mode' => 'owner', 'ids' => 1]);
            Если вызывать кэшируемый msProductKits, то вечное сохранение документа. Не подскажите в чем может быть дело? Хотел при сохранении комплекта суммировать стоимость его компонентов и сохранить в price.
              Наумов Алексей
              Наумов Алексей Администратор
              25 февраля 2021, 16:15
              Не нужно вызывать сниппет в плагине, реально плохая идея… ну как из пушки по воробьям…
              Напишите просто нужный вам запрос, он будет не очень сложным.
              Хотя, конечно, в целом сработать то должно было) Может еще в чем дело? Сниппет строку вернет, это учитывали?
                Владимир
                Владимир Старожил
                25 февраля 2021, 16:28
                Строку учитывал. К сожалению, не силен в этом. В основном по описаниям компонентов работаю. Спасибо.
                  Владимир
                  Владимир Старожил
                  25 февраля 2021, 17:30
                  С запросом справился)
                    Наумов Алексей
                    Наумов Алексей Администратор
                    26 февраля 2021, 09:18
                    Отлично! Было бы интересно услышать отзыв по компоненту, я сам его использовал только на одном сайте и обратная связь не помешала бы, возможно стоит что-то улучшить.
                      Владимир
                      Владимир Старожил
                      26 февраля 2021, 14:24
                      Компонент полезный и удобный в плане администрирования, для моей задачи очень хорошо подошел. Из предложений, в моем случае, было бы удобно если в системных настройках была возможность ограничить не более одного товара из каждой категории. И хорошо бы реализовать цену всего комплекта суммированием стоимости товаров, входящих в состав комплекта, но это можно и самостоятельно. Спасибо за компонент!
                        Владимир
                        Владимир Старожил
                        26 февраля 2021, 15:17
                        Еще цену входящих в комплект товаров можно в таблицу добавить.
                          alexbox
                          alexbox Старожил
                          20 мая 2021, 10:31
                          В подборе позиций к комплекту было бы удобно поиск по артикулу
                            Андрей Шевяков
                            Андрей Шевяков Старожил
                            19 июня 2025, 14:34
                            Этот функционал очень нужен, поддерживаю. Просто вывести цены товаров в комплекте на вкладке комплекты
                alexbox
                alexbox Старожил
                20 мая 2021, 10:49
                Ещё идея для развития:

                сейчас в корзину попадает товар с артикулом и названием набора — «Набор такой то», Арт. 0000
                что если сделать настройку, чтобы на усмотрение Админа сайта выбирать, отправлять в корзину Набор, или «Товары в наборе по позиционно».

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

                Некоторые товары требуют особенного учета, сертификации. Делать наборы и выставлять их в продажу через интернет-магазин — нагрузка на бухгалтерию и гемморой.

                Если бы наборы товаров продавались как набор, но в фискальный чек попадали поштучно, это было бы супер удобно!

                За такой компонент я бы и заплатил ))
                  Наумов Алексей
                  Наумов Алексей Администратор
                  20 мая 2021, 11:03
                  Рациональность в этом всем есть… да…
                  У меня не было такой задачи… я вообще в основном все сделал только для того, чтобы в админке этим было удобно управлять.

                  Советую посмотреть в сторону msSetInCart, может он даст нужный функционал?
                  alexbox
                  alexbox Старожил
                  20 мая 2021, 10:53
                  Не хватает примеров вывода сниппета msProductKits
                  стандартных чанков tpl
                    Игорь
                    Игорь Старожил
                    09 июня 2021, 21:09
                    Здравствуйте.
                    Есть форма распечатывания заказа из админки по методу modx.pro/howto/17280.
                    Пытаюсь добавить туда состав комплекта — мне нужно просто получить список id товаров, включенных в комплект. Но, почему-то сниппет
                    {$ids = $_modx->runSnippet('!msProductKits', ['mode' => 'owner','ids' => 1,'resource' => $prodid])}
                    в данном чанке не срабатывает (на страницах сайта во фронтенде работает нормально).
                    Как ещё можно получить id товаров из комплекта?
                      Наумов Алексей
                      Наумов Алексей Администратор
                      10 июня 2021, 08:59
                      Добрый день.
                      Я так понимаю, у вас там некий файл с кодом, где нужны id товаров?

                      Сделайте запрос в бд напрямую, не запускайте сниппет.
                      Вот вырезка кода, только поправьте ее, я просто скопировал кусок:
                      // addPackage для загрузки модели
                      $modx->addPackage('msproductkits', MODX_CORE_PATH . 'components/msproductkits/model/');
                      
                      // Build query
                      $c = $modx->newQuery('msProductKitItem');
                      $c->select($modx->getSelectColumns('msProductKitItem', 'msProductKitItem'));
                      $c->where(['active' => 1, $mode => $resource]);
                      $kitItems = $modx->getIterator('msProductKitItem', $c);
                      // далее foreach
                        Игорь
                        Игорь Старожил
                        10 июня 2021, 09:01
                        вот без этой строчки в сниппете:
                        $resource = intval($modx->getOption('resource', $scriptProperties, $modx->resource->get('id'), true));
                        работает почему-то
                          Наумов Алексей
                          Наумов Алексей Администратор
                          10 июня 2021, 09:10
                          Вы же запускаете сниппет в контексте mgr, верно?
                          Там нет $modx->resource, здесь и возникает ошибка…
                            Игорь
                            Игорь Старожил
                            10 июня 2021, 09:14
                            да, все верно — в контексте mgr. Спасибо
                        Алексей Корчагин
                        20 февраля 2026, 07:22
                        Доброго времени суток.
                        Подскажите, как правильно составлять наборы при выгрузке товаров через mSync? Делать прямые запросы на добавление этих связей? Собираюсь делать в событии где известен id ресурса.
                          Наумов Алексей
                          Наумов Алексей Администратор
                          20 февраля 2026, 10:08
                          Добрый день! Я этот компонент давно делал, и еще лет 5 не возвращался к нему… он работоспособен, все в этом плане нормально (ну по крайней мере с php не выше 8 версии я думаю).

                          Что касается интеграции с mSync — вам придется самим думать как это сделать, руками создавать записи в БД. Никаких других механизмов нет.

                          Смотрите схему БД, там всё просто: github.com/createit-ru/msProductKits/blob/master/core/components/msproductkits/model/schema/msproductkits.mysql.schema.xml
                            Олег Захаров
                            Олег Захаров Старожил
                            18 апреля 2026, 01:10
                            У вас репозиторий закрылся?
                              Наумов Алексей
                              Наумов Алексей Администратор
                              18 апреля 2026, 15:34
                              открыл, не знаю, почему он закрыт оказался) но, стоит учесть, что код там очень старый
                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                          31