[msOptionsPrice2] работа с остатками

Опишу решение ряда проблем с которыми столкнулся сам. msOptionsPrice2 очень крутое решение для minishop2 но для нормальной работы с остатками там очень мало функционала.
Проблемы:
  1. На странице каталога и товара нет плейсхолдера, с помощью которого можно было бы скрыть кнопку добавления в корзину и вывести свою информацию
  2. На странице каталога при добавлении товара проверяется на наличии первая модификация, и, если она отсутствует, то выскакивает оповещение о недоступности товара
  3. На миникарточке указана неправильная цена, т.к. выводится цена продукта, а не цена модификации
Инструкция под катом


Первым делом создадим сниппет для чанка миникарточек на странице каталога, назовем его допустим getRemOpt и передадим в него ID текущего обрабатываемого ресурса:
[[!getRemOpt?
  &id=`[[+id]]`
]]
Код сниппета с комментариями:
<?php
//Получаем все модификации по текущему товару
$q = ['rid' => $id];
$res = $modx->getCollection('msopModification', $q);
foreach ($res as $item) {
  //формируем массив из остатков и цен всех модификаций этого товара
  $prod[] = ['count' => $item->get('count'), 'price' => $item->get('price')];
  //формируем массив из модификаций которые больше нуля
  if ($item->get('count') > 0) {
    $opt[] = $item->toArray()['options'];
  }
}
//Проверяем есть ли у нас в наличии хоть одна из модификаций текущего товара
$res = false;
foreach ($prod as $a) {
    if ($a['count'] != 0) {
      $res = true;
      break;
    }
}
for ($i = 0; $i < count($prod); $i++) {
  if ($prod[$i]['count'] > 0) {
    $opt_price = $prod[$i]['price'];
    break;
  }
}
//если есть, то устанавливаем плейсхолдер rem = 1 и цену первой модификации
if ($res) {
  $modx->setPlaceholder('rem', '1');
  $modx->setPlaceholder('opt_price', $opt_price);
} else {
  $modx->setPlaceholder('rem', '0');
  $modx->setPlaceholder('opt_price', $modx->getPlaceholder('price'));
}
//Получаем ключ и значению первой модификации которая в наличии
if ($res) {
  $opt_key = key($opt[0]);
  $opt_val = $opt[0][$opt_key];
  $modx->setPlaceholder('opt_key', '['.$opt_key.']');
  $modx->setPlaceholder('opt_val', $opt_val);
} else {
  $modx->setPlaceholder('opt_key', '');
  $modx->setPlaceholder('opt_val', '');
}
return ;
Главная особенность этого сниппета в том, что если есть хоть одна модификация в наличии, то в плейсхолдер rem приходит единица, а если все модификации отсутствуют, то туда же приходит 0. Теперь делаем простую проверку в чанке msProduct:
[[+rem:eq=`0`:then=`Ожидаем поступления`:else=`Кнопка добавления в корзину`]]
Далее нам нужно изменить инпут минишопа, который отвечает за опции, для того, чтобы подсовывать туда только ту опцию, которая есть в данный момент в наличии вот так:
<input type="hidden" name="options[[+opt_key]]" value="[[+opt_val]]">
Ну и конечно же заменяем [[+price]] на [[+opt_price]], для того, чтобы выводилась цена модификации, которая полетит в корзину.
На этом в принципе все, сниппет getRemOpt можно использовать как внутри карточки товаране проверялось, так и на странице каталога в msProduct
Также, хочу заметить что у msOptionPrice2 есть свои JQUERY события (к сожалению не документированные) при переключении опций, к примеру таким образом у меня скрываются кнопки добавления в корзину тогда, когда у выбранной опции остаток равен нулю
<script>
  $(document).on('msoptionsprice_product_action', function (e, action, form, r) {
      if (action == 'modification/get' && r.success && r.data) {
          var m = r.data.modification || {};
          var o = r.data.options || {};
        if (!m['count']) {
            miniShop2.Message.error('Нет в наличии');
            $('.addNotification').fadeIn();
            $('.hide_remains').fadeOut();
        }
        else {
             $('.addNotification').fadeOut();
             $('.hide_remains').fadeIn();
        }
      }
    
  });
</script>
Надеюсь, что кому то облегчил жизнь своим говнокодом, если кто перепишет в комментариях на нормальный код мои писульки, буду только рад. Надеюсь когда нибудь этот функционал появится в msOptionPrice2 из коробки, и будет адекватно задокументирован. Спасибо Володе, что помог разобраться в его крутом дополнении

P.s. обновил топик, было добавлено решение, для того, чтобы на миникарточке выводить цену модификации
Pavel Zarubin
08 августа 2017, 13:15
modx.pro
14
4 885
+4
Поблагодарить автора Отправить деньги

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

Дмитрий Суворов
08 августа 2017, 20:22
0
Я делал иначе, если кратко: вызывал сниппет msOptionsPrice.modification с параметром where, в котором задавал условие count>0, результат в плейсхолдер. После чего проверяем плейсхолдер, если пуст — скрываем кнопку, пишем свою информацию, если нет — то соответственно выводим кнопку и т.д.
    Pavel Zarubin
    08 августа 2017, 20:28
    0
    Как вариант, а как решил проблему с тем, что при добавлении добавляется первая по порядку модификация?
    Pavel Zarubin
    08 августа 2017, 20:50
    0
    P.s. обновил топик, было добавлено решение, для того, чтобы на миникарточке выводить цену модификации
      Алексей
      23 января 2018, 12:29
      +1
      Добрый день! Совместим ли компонент msOptionPrice с компонентом msync? Необходимо выгружать кол-во товара(остатки). Или быть может есть у кого готовый вариант как сделать остатки в tv параметре. И потом как-то проверять, при добавлении в корзину. Весь функционал msoptionprice2 по сути не нужен.
        Pavel Zarubin
        23 января 2018, 13:37
        0
        Добрый, я не автор компонента msOptionPrice, вам лучше задать его автору)
        Но если не нужен функционал msOptionPrice2, то легче сделать остатки используя tv-параметры или msProductRemains
        Vlad Brise
        06 декабря 2018, 22:13
        +3
        Блин круто, спасибо :)
          Артур Шевченко
          03 февраля 2021, 23:51
          0
          А вот это всё не баги компонента их не фиксили? Про кнопку точно нет, а вот насчет того, что проверяется только первая модификация это как-то странно, нет?
            Pavel Zarubin
            04 февраля 2021, 00:11
            0
            Статья 2017 года, 4 года уже прошло, я думаю если бы этот функционал был кому то нужен, его бы уже 10 раз пофиксили)
              Артур Шевченко
              04 февраля 2021, 00:22
              0
              Мне был нужен, но я не догадался поискать готовые решения. И придуманный мной костыль не догадался сюда написать, слава богу, а то вдруг бы ты увидел)))
            Сергей Карпович
            02 марта 2021, 17:29
            0
            Всем привет. Вопрос.
            Если у меня есть товары с модификациями и без, как настроить учет остатков?
            Для всех товаров создать модификацию Остаток, без изменения цены?
            Или создать обычную опцию, и ее как то привязать к msOptionsPrice2, что бы был учет остатков?
              Алексей
              27 апреля 2021, 16:06
              0
              Тоже интересует данный вопрос…
              У меня настроен mSync с 1С, написан плагин который создаёт модификации в msOptionPrice2 (каждые раз при обновлении из 1С идёт проверка есть ли уже такая опция или нет, если нет создаёт, а то раньше просто добавлял бесконечные модификации и хорошо что у всех товаров есть модификации, а то тогда становится всего нет в наличии), а есть просто товары без привязки к 1С и вот нужно что бы они просто покупались… потому что у них нет модификаций… я вышел из положения просто создав пустую модификацию с количеством в 1000000 и теперь можно положить в корзину xD
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              11