Цена товара в зависимости от выбранного ТВ [решено]

Доброго дня, нужна помощь.
Ни разу не писал плагины, но полагаю без этого здесь не обойтись.

Есть ТВ с возможными значениями:
@EVAL $output = $modx->runSnippet('pdoResources',array( 
'parents'=> $modx->resource->parent,
'resources'=> -$modx->resource->id,
'tpl'=>'@CODE:[[+pagetitle]]==[[+id]]', 
'showUnpublished'=>'1',
'limit'=>'0',
'depth'=>'0',
'hideContainers'=>'1', 
'outputSeparator'=>'||')); 
return '' . $output;
В админке я чекбоксами выбираю подходящие товары.

Задача сделать так, чтобы в родное поле price (minishop2) в админке подставлялось значение товара с наименьшей ценой.



во фронтенде пока вывожу костылём:
{if $template == 5}
{set $my}
{$clothes | replace :'||':','}
{/set}    
{$_modx->runSnippet('!msProducts', [      
'parents'=> $parent,
'resources'=> $my,
'tpl'=>'@INLINE: {$price} руб.', 
'showUnpublished'=> 1,
'limit'=> 1,
'depth'=> 0,
'sortby' => '{"price":"ASC"}',
'hideContainers'=> 1,
'toPlaceholder'=> 'res',
 ])}
 [[+res:empty=`<small>нет в наличии</small>`]]
 {else}
 {$price} {'ms2_frontend_currency' | lexicon}
{/if}
vrm13
16 октября 2018, 15:09
modx.pro
1 460
0
Поблагодарить автора Отправить деньги

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

vrm13
17 октября 2018, 10:31
0
Начну мыслить вслух, если вы не против.
Пытаюсь понять как пишутся плагины, для этого делаю что-то простое, например, при сохранении документа с шаблоном 5 нужно прибавить к цене 100 р. делаю вот таким образом:

<?php
if ($modx->event->name = 'OnBeforeDocFormSave') {
	    if ($resource->get('template') == 5) {
        $price = $product->get('price');
        return $price + 100;
	    }
        break;
}
но при сохранении страницы бесконечная загрузка и в журнале ошибок ничего. на каком шаге ошибка, пока не пойму.

Наверное стоит ещё сказать зачем такой костыль, когда есть дополнения типа msoptionsprice2 и другие.
Дело в том, что я делаю загрузку каталога с помощью msync. Так как в каталоге 1с размеры и цвета товаров — это отдельные товары, а на сайт я такое вываливать не хочу — я создаю товар с шаблоном 5 и через TV, с возможными значениям (описан в начале) назначаю ему нужные товары. В целом всё работает, но цену приходится назначать руками и следить за её изменениями.

Решение вижу в том, чтобы через плагин подставить значение товара из той самой ТВ с наименьшей ценой, при сохранении документа.
Если у кого будет минутка, направьте пожалуйста, а пока ковыряю дальше.
    Андрей
    17 октября 2018, 10:47
    1
    +1
    Примерно так должно работать

    if ($modx->event->name == 'OnDocFormSave') {
    
    	if ($resource->template != 5) { // id шаблона с товаром
    		return;
    	}
    
    	// получаем id выбранных в TV продуктов
    	$tv = $resource->getTVValue('имя_tv_с_чекбоксами');
    
    	if (empty($tv)) {
    		return;
    	}
    
    	$ids = explode($tv, ',');
    
    	// получаем сами продукты
    	$products = $modx->getCollection('msProduct', [
    		'id:IN' => $ids
    	]);
    
    	if ($products) {
    
    		$prices = [];
    		
    		// получаем цены для выбранных продуктов
    		foreach ($products as $product) {
    			$prices[] = $product->get('price');
    		}
    
    		// получаем минимальную цену
    		$min_price = min($prices);
    
    		if ($min_price) {
    			// сохраняем цену для товара
    			$resource->set('price', $min_price);
    			$resource->save();
    		}
    
    	}
    }
      Андрей
      17 октября 2018, 10:51
      +1
      Для тв с чекбокасми возможно нужно поставить «тип вывода» — «разделитель» запятая.
        vrm13
        17 октября 2018, 11:36
        0
        тв с таким типом стоит, но что интересно если в чанке просто вывести {$clothes} значения всё равно — 1 || 2 || 3

        Пробую ваш код:

        <?php
        if ($modx->event->name == 'OnDocFormSave') {
        
        	if ($resource->template != 5) { // id шаблона с товаром
        		return;
        	}
        
        	// получаем id выбранных в TV продуктов
        	$tv = $resource->getTVValue('clothes');
        
        	if (empty($tv)) {
        		return;
        	}
        
        	$ids = explode($tv, ',');
        
        	// получаем сами продукты
        	$products = $modx->getCollection('msProduct', [
        		'id:IN' => $ids
        	]);
        
        	if ($products) {
        
        		$prices = [];
        		
        		// получаем цены для выбранных продуктов
        		foreach ($products as $product) {
        			$prices[] = $product->get('price');
        		}
        
        		// получаем минимальную цену
        		$min_price = min($prices);
        
        		if ($min_price) {
        			// сохраняем цену для товара
        			$product->set('price', $min_price);
        			$resource->save();
        		}
        
        	}
        }
        системное событие поменял на OnDocFormSave. Ресурс сохраняется нормально, но никаких изменений и в журнале ошибок пусто. Существует ли какой-то способ поиска ошибок в таком случае? как в сниппетах showLog например
          Андрей
          17 октября 2018, 11:43
          +1
          Попробуйте разделитель в плагине поменять тогда на  ||

          Ошибки можно записывать в журнал ошибок Управление — Отчеты — Журнал ошибок
          $modx->log(1, print_r($ids, 1)); // распечатает массив с ids
            vrm13
            17 октября 2018, 12:00
            0
            полезная вещь!
            $modx->log(1, print_r($ids, 1)); // распечатает массив с ids
            массив пустой —
            Array
            (
                [0] => ,
            )
            хотя
            $modx->log(1, print_r($tv, 1));
            выдаёт правильные id причём с разделителем запятая: 2689,2690,2691,2692,2693,2951,2952
              Андрей
              17 октября 2018, 12:05
              +1
              Ну да, я explode не правильно написал, наоборот надо, сначала разделитель

              $ids = explode(',', $tv);
                vrm13
                17 октября 2018, 12:11
                +1
                Огромное спасибо! Теперь работает.

                Рабочий плаин:
                <?php
                if ($modx->event->name == 'OnDocFormSave') {
                
                	if ($resource->template != 5) { // id шаблона с товаром
                		return;
                	}
                
                	// получаем id выбранных в TV продуктов
                	$tv = $resource->getTVValue('clothes');
                
                	if (empty($tv)) {
                		return;
                	}
                
                	$ids = explode(',', $tv);
                
                	// получаем сами продукты
                	$products = $modx->getCollection('msProduct', [
                		'id:IN' => $ids
                	]);
                
                	if ($products) {
                
                		$prices = [];
                		
                		// получаем цены для выбранных продуктов
                		foreach ($products as $product) {
                			$prices[] = $product->get('price');
                		}
                
                		// получаем минимальную цену
                		$min_price = min($prices);
                
                		if ($min_price) {
                			// сохраняем цену для товара
                			$resource->set('price', $min_price);
                			$resource->save();
                		}
                
                	}
                }
                Благодарен вам! И научили как и за меня написали.
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      8