[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. обновил топик, было добавлено решение, для того, чтобы на миникарточке выводить цену модификации
08 августа 2017, 16:15    Pavel Zarubin   G+  
7    282 +4

Комментарии (3)

  1. Дмитрий Суворов 08 августа 2017, 20:22 # 0
    Я делал иначе, если кратко: вызывал сниппет msOptionsPrice.modification с параметром where, в котором задавал условие count>0, результат в плейсхолдер. После чего проверяем плейсхолдер, если пуст — скрываем кнопку, пишем свою информацию, если нет — то соответственно выводим кнопку и т.д.
    1. Pavel Zarubin 08 августа 2017, 20:28 # 0
      Как вариант, а как решил проблему с тем, что при добавлении добавляется первая по порядку модификация?
    2. Pavel Zarubin 08 августа 2017, 20:50 # 0
      P.s. обновил топик, было добавлено решение, для того, чтобы на миникарточке выводить цену модификации
      Вы должны авторизоваться, чтобы оставлять комментарии.