при клике на radio идет пересчет итоговой суммы в orderUI, в зависимости от способов(оплаты доставки) я так поняла. попробуй код запуска соб...
Скидка от суммы корзины в MiniShop3: плагин на msOnGetCartCost за 20 строк
Клиент просит скидку 5% от 5 000 ₽, 10% от 10 000 ₽ или фикс 500 ₽ от 3 000 ₽. В miniShop2 вы, скорее всего, лезли в msOnGetOrderCost. В MiniShop3 расчёт разбит на три события: корзина, доставка, комиссия оплаты. Скидку на товары вешаем на msOnGetCartCost.
Документация: События стоимости.
MiniShop3 считает сумму корзины и вызывает плагины на msOnGetCartCost. В $scriptProperties['cost'] приходит текущая сумма. Новую сумму задаём через $modx->event->returnedValues['cost']. Значение подхватится в корзине, на оформлении и в API.
События с префиксом Before умеют остановить операцию через output(). msOnGetCartCost только меняет цифру.
Один плагин, правила в массиве $config вверху файла. Фикс применяется первым, процент считается от остатка. Данные для витрины кладём в $modx->eventData['ms3CartDiscount'].
Лог: core/cache/logs/error.log. Строку удалите после проверки.
Отдельный плагин на msOnGetStatusCart. Читает тот же ключ ms3CartDiscount.
В чанке корзины (Fenom): {$status.discount_label}.
Документация: События стоимости.
Что делает msOnGetCartCost
MiniShop3 считает сумму корзины и вызывает плагины на msOnGetCartCost. В $scriptProperties['cost'] приходит текущая сумма. Новую сумму задаём через $modx->event->returnedValues['cost']. Значение подхватится в корзине, на оформлении и в API.
События с префиксом Before умеют остановить операцию через output(). msOnGetCartCost только меняет цифру.
MS2: msOnGetOrderCost заменили на msOnGetCartCost, msOnGetDeliveryCost, msOnGetPaymentCost.
Плагин: скидка от суммы корзины
Один плагин, правила в массиве $config вверху файла. Фикс применяется первым, процент считается от остатка. Данные для витрины кладём в $modx->eventData['ms3CartDiscount'].
<?php
/**
* Cart discount by order amount.
* Event: msOnGetCartCost
*/
if ($modx->event->name !== 'msOnGetCartCost') {
return;
}
$cartCost = (float) ($scriptProperties['cost'] ?? 0);
if ($cartCost <= 0) {
return;
}
$config = [
'fixed' => [
'enabled' => true,
'threshold' => 3000,
'amount' => 500,
],
'percent_tiers' => [
10000 => 10,
5000 => 5,
],
];
$discountParts = [];
$costAfterFixed = $cartCost;
if (
$config['fixed']['enabled']
&& $cartCost >= $config['fixed']['threshold']
) {
$fixedAmount = min($config['fixed']['amount'], $cartCost);
$discountParts['fixed'] = $fixedAmount;
$costAfterFixed = $cartCost - $fixedAmount;
}
$appliedPercent = 0;
if ($costAfterFixed > 0) {
foreach ($config['percent_tiers'] as $threshold => $percent) {
if ($costAfterFixed < $threshold) {
continue;
}
$discountParts['percent'] = round($costAfterFixed * $percent / 100, 2);
$appliedPercent = $percent;
break;
}
}
$totalDiscount = array_sum($discountParts);
if ($totalDiscount <= 0) {
return;
}
$returnedValues = &$modx->event->returnedValues;
$returnedValues['cost'] = max(0.0, $cartCost - $totalDiscount);
$modx->eventData['ms3CartDiscount'] = [
'total' => $totalDiscount,
'parts' => $discountParts,
'percent' => $appliedPercent,
];Только процент или только фикс
Меняете $config, второй плагин не нужен.- Только процент: 'fixed' => ['enabled' => false, 'threshold' => 0, 'amount' => 0]
- Только фикс: 'percent_tiers' => []
Установка
- Элементы → Плагины → Создать. Имя: MS3 Cart Discount.
- Вставьте код выше.
- Системные события → msOnGetCartCost.
- Сохраните, очистите кэш.
- Проверьте корзину.
Проверка
- 3 500 ₽ → 3 000 ₽ (минус 500 ₽ фикс)
- 6 000 ₽ → 5 700 ₽ (минус 5%)
- 10 500 ₽ → 9 450 ₽ (минус 10%)
- 12 000 ₽ → 10 950 ₽ (500 ₽ + 10% от 11 500 ₽)
$modx->log(
modX::LOG_LEVEL_ERROR,
'[MS3CartDiscount] cost=' . $cartCost . ' discount=' . $totalDiscount
);Лог: core/cache/logs/error.log. Строку удалите после проверки.
Показать скидку в корзине
Отдельный плагин на msOnGetStatusCart. Читает тот же ключ ms3CartDiscount.
<?php
if ($modx->event->name !== 'msOnGetStatusCart') {
return;
}
$discount = $modx->eventData['ms3CartDiscount'] ?? null;
if ($discount === null || ($discount['total'] ?? 0) <= 0) {
return;
}
$labelParts = [];
if (!empty($discount['parts']['fixed'])) {
$labelParts[] = '−' . number_format($discount['parts']['fixed'], 0, '', ' ') . ' ₽';
}
if (!empty($discount['parts']['percent']) && !empty($discount['percent'])) {
$labelParts[] = $discount['percent'] . '%';
}
$label = 'Скидка ' . implode(' + ', $labelParts);
$status = $scriptProperties['status'];
$status['discount_label'] = $label;
$returnedValues = &$modx->event->returnedValues;
$returnedValues['status'] = $status;В чанке корзины (Fenom): {$status.discount_label}.
Три частые ошибки
- Без ссылки на returnedValues.
$values = $modx->event->returnedValues;— не сработает. Нужно: $returnedValues = &$modx->event->returnedValues; - Пустая корзина. $cartCost === 0 — плагин выходит, это нормально.
- Три плагина на одном событии. Лучше один плагин и $config, чем три файла с разными ключами в eventData.
Дальше
- Скидка на доставку → msOnGetDeliveryCost
- Комиссия оплаты → msOnGetPaymentCost
- Блокировка без остатка → msOnBeforeAddToCart
- События MiniShop3 ·
- Работа с плагинами ·
- Исходники github.com/modx-pro/MiniShop3 Баг или идея — в Issues.
Поблагодарить автора
Отправить деньги
0