Как изменить цену в корзине исходя из веса?
        В корзине особенная логика формирования цены должна быть, и она зависит от веса (weight), а не от количества.
Если в коротко, то при достижении веса например в 400 грамм суммарно для всех товаров в корзине должна применяться для всех них скидка в 20% например.
Это нестандартная задача, обычно оптовые цены зависят от количества, а не от веса.
Я вижу решение проблемы из двух этапов:
Сделал плагин на события msOnAddToCart, msOnBeforeAddToCart, msOnChangeInCart, msOnRemoveFromCart:
Следующий кусок плагина по логике должен был бы мне подходить, но ругается в логи сервера при попытке иницилазиации класса на строчке if($miniShop2->initialize($modx->context->key, $scriptProperties));:
Почему этот код, который ранее у других работал ругается у меня? Из-за последних изменений в miniShop2?
Как заставить его работать?
Подытожу что мне нужно: у меня в плагине должен быть доступ к общим характеристикам всей корзины, а именно к общему весу. Далее мне нужно поменять изменить цену для каждого из товаров отдельно и проверить чтобы общая сумма была со скидкой.
По второму пункту (фронтенду), думаю будет ясно как поступить если будет работать первый, т.к. фронтенд вытекает из бэкэнда.
    
    
                                                                                
            Если в коротко, то при достижении веса например в 400 грамм суммарно для всех товаров в корзине должна применяться для всех них скидка в 20% например.
Это нестандартная задача, обычно оптовые цены зависят от количества, а не от веса.
Я вижу решение проблемы из двух этапов:
- бэкэнд из плагина
 - фронтэнд на js-кэллбэке
 
Сделал плагин на события msOnAddToCart, msOnBeforeAddToCart, msOnChangeInCart, msOnRemoveFromCart:
<?php
if ($modx->event->name = 'msOnBeforeAddToCart' || $modx->event->name = 'msOnChangeInCart' || $modx->event->name = 'msOnRemoveFromCart' ) {
    
    // Тут цена успешно меняется, характеристики добавляются, но для конкретного товара, но нет доступа к общей корзине
    // Но динамически это не происходит, т.к. ругается в консоль браузера на ошибки на сервере
    // Оба варианта с одинаковыми результатами
    
    // Ваниант 1
    $values = & $modx->event->returnedValues;
    $values['count'] = $count + 10;
    $values['price'] = 2;
    $values['options'] = array('size' => '99');
    // Вариант 2
    $procent = 90;
    $price = $product->get('price');
    $rate = $procent * $price / 100;
    $price = $price - $rate;
    $product->set('price', $price);
    $product->set('price', 111);
    $modx->log(modX::LOG_LEVEL_ERROR, "cart: ".print_r($product->get('price'),1) );
  
}Приведённые 2 варианта плагина я забраковал по описанным выше причинам.Следующий кусок плагина по логике должен был бы мне подходить, но ругается в логи сервера при попытке иницилазиации класса на строчке if($miniShop2->initialize($modx->context->key, $scriptProperties));:
<?php
switch ($modx->event->name) {
    case 'msOnChangeInCart': case 'msOnAddToCart': case 'msOnRemoveFromCart':
        $miniShop2 = $modx->getService('minishop2','miniShop2',
        	MODX_CORE_PATH . 'components/minishop2/model/minishop2/', $scriptProperties);
        if (!($miniShop2 instanceof miniShop2)) return '';
        // Инициализируем класс в текущий контекст
        if($miniShop2->initialize($modx->context->key, $scriptProperties));
        $total_count = $miniShop2->cart->status()['total_count'];
        $tmp = $miniShop2->cart->get();
        foreach ($tmp as $key1 => $value) {
            if ($product = $modx->getObject('msProduct', $value['id'])) {
            	$tmp[$key1]['price'] = 22222222222;
            }
        }
        
        if ($total_count > 4) { // если 5 и более товаров - оптовые цены, в интернет-магазине оптовые цены забиваются в поле article
            foreach ($tmp as $key1 => $value) {
                if ($product = $modx->getObject('msProduct', $value['id'])) {
                	$tmp[$key1]['price'] = 22222222222;
                }
            }
        }
        else {
            foreach ($tmp as $key1 => $value) {
                if ($product = $modx->getObject('msProduct', $value['id'])) {
                	$tmp[$key1]['price'] = 11111111;
                }
            }
        }
        $miniShop2->cart->set($tmp);
        break;
}Логи:(ERROR @ /home/s***/www/core/components/minishop2/model/minishop2/minishop2.class.php : 95) Recoverable error: Object of class msCartHandler could not be converted to string
(ERROR @ /home/s***/www/core/components/minishop2/model/minishop2/minishop2.class.php : 104) Recoverable error: Object of class msCartHandler could not be converted to stringВ файле minishop2.class.php на этих строчках регистрация клиентского скрипта:$this->modx->regClientCSS(str_replace($config['pl'], $config['vl'], $css)); // 95 строчка
$this->modx->regClientScript(str_replace($config['pl'], $config['vl'], $js)); // 104 строчкаПочему этот код, который ранее у других работал ругается у меня? Из-за последних изменений в miniShop2?
Как заставить его работать?
Подытожу что мне нужно: у меня в плагине должен быть доступ к общим характеристикам всей корзины, а именно к общему весу. Далее мне нужно поменять изменить цену для каждого из товаров отдельно и проверить чтобы общая сумма была со скидкой.
По второму пункту (фронтенду), думаю будет ясно как поступить если будет работать первый, т.к. фронтенд вытекает из бэкэнда.
Комментарии: 5
                А зачем еще раз инициализировать minishop2? 
Эти события уже получают $cart
попробуйте так:
                    Эти события уже получают $cart
попробуйте так:
<?php
switch ($modx->event->name) {
    case 'msOnChangeInCart': case 'msOnAddToCart': case 'msOnRemoveFromCart': 
        $total_count = $cart->status()['total_count'];
        $tmp = $cart->get();
        foreach ($tmp as $key1 => $value) {
            if ($product = $modx->getObject('msProduct', $value['id'])) {
            	$tmp[$key1]['price'] = 22222222222;
            }
        }
        
        if ($total_count > 4) { // если 5 и более товаров - оптовые цены, в интернет-магазине оптовые цены забиваются в поле article
            foreach ($tmp as $key1 => $value) {
                if ($product = $modx->getObject('msProduct', $value['id'])) {
                	$tmp[$key1]['price'] = 22222222222;
                }
            }
        }
        else {
            foreach ($tmp as $key1 => $value) {
                if ($product = $modx->getObject('msProduct', $value['id'])) {
                	$tmp[$key1]['price'] = 11111111;
                }
            }
        }
        $cart->set($tmp);
        break;
}            
                Действительно, зачем это я… Тупое копирование с примеров, которые у других работали.
Спасибо тебе, добрый человек, всё работает как и задумывалось!
Вот что получилось (на будущее):
Плагин:
                    Спасибо тебе, добрый человек, всё работает как и задумывалось!
Вот что получилось (на будущее):
Плагин:
<?php
switch ($modx->event->name) {
    case 'msOnChangeInCart': case 'msOnAddToCart': case 'msOnRemoveFromCart': 
        $total_count = $cart->status()['total_count'];
        $total_weight = $cart->status()['total_weight'];
        
        $procent = 20;
        
        $tmp = $cart->get();
        
        if ($total_weight > 400) {
            foreach ($tmp as $key1 => $value) {
                if ($product = $modx->getObject('msProduct', $value['id'])) {
                    $price = $product->get('price');
                    $rate = $procent * $price / 100;
                    $price = $price - $rate;
                	$tmp[$key1]['price'] = $price;
                    $modx->log(modX::LOG_LEVEL_ERROR, "cart: ".print_r($price,1) );
                	
                	
                }
            }
        }
        else {
            foreach ($tmp as $key1 => $value) {
                if ($product = $modx->getObject('msProduct', $value['id'])) {
                	$tmp[$key1]['price'] = $product->get('price');
                }
            }
        }
        $cart->set($tmp);
    break;
}Ну и на фронтенде повторение функционала:<script>
    miniShop2.Callbacks.add('Cart.change.response.success', 'response_log', function(e) {
        var total_weight = e.data.total_weight;
        if(total_weight > 400) {      
            console.log('opt');
            $('#msCart .price .procent').text('-20%');
        } else {
            $('#msCart .price .procent').text('');
        }
    });
    miniShop2.Callbacks.add('Cart.remove.response.success', 'response_log', function(e) {
        var total_weight = e.data.total_weight;
        if(total_weight > 400) {      
            console.log('opt');
            $('#msCart .price .procent').text('-20%');
        } else {
            $('#msCart .price .procent').text('');
        }
    });
</script>            
                Подскажите, вы создали плагин через админку? почему то у меня ничего не происходит            
                    
                да, через админку, на 3 события, которые указаны в начале плагина.            
                    
                А почему не сделать расширением корзины? Я так решаю подобные задачи.
Пример в доках: docs.modx.pro/components/minishop2/development/service/connection#Пример-подключения-собственного-класса-доставки
                    Пример в доках: docs.modx.pro/components/minishop2/development/service/connection#Пример-подключения-собственного-класса-доставки
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.