You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Защита total от ухода в минус + UX-маркер для скидок в настройках доставки/оплаты #265
После #211 / #246 поле price у способов доставки и оплаты поддерживает отрицательные значения и проценты — это позволяет настраивать скидки за способ оплаты/доставки (например, «−5% за оплату наличными», «−200₽ за самовывоз»).
Текущая реализация оставляет два открытых вопроса:
Нет защиты от отрицательного total заказа.isAllowedPercent ограничивает только проценты диапазоном -100..100, а фиксированная скидка вроде -99999 сохранится без вопросов. При накоплении скидок из нескольких источников (доставка + оплата) total может уйти в минус. Потенциальный фрод-вектор.
UX в админке не различает наценку и скидку. Поле одно, plain textfield, подсказка в lexicon говорит «может быть отрицательной». Оператор легко теряет знак при копи-пасте или вводе с клавиатуры и продаёт в минус.
Предложение
1. Защита total в OrderService::recalculate()
Финальная проверка после применения всех слагаемых:
if ($total < 0) {
$this->modx->log(
modX::LOG_LEVEL_WARN,
"[Order] Negative total for order #{$order->id}: "
. "subtotal={$subtotal}, delivery={$deliveryCost}, payment={$paymentCost}. "
. "Clamping to 0."
);
$total = 0;
}
Записывать в лог все слагаемые, чтобы при ручном разборе было видно, какая настройка увела заказ в минус.
2. UX-маркер «Скидка / Наценка» в админке
В Vue-формах способов доставки и оплаты рядом с полем price:
Значение начинается с - → зелёный бейдж «Скидка».
Положительное → серый бейдж «Наценка».
0 или пусто → без бейджа.
Реактивная подсказка по v-model поля, без серверной валидации. Помогает оператору сразу видеть знак.
Из scope намеренно вынесено
Размазывание скидки по позициям заказа для чеков 54-ФЗ — это задача компонентов-провайдеров фискализации, которые работают со своим API эквайринга и знают его требования. MS3 отдаёт им итоговые цифры заказа, дальше их зона ответственности.
Отдельное поле discount на моделях — не нужно. Знак числа в price — естественный способ выразить наценку/скидку, ломать его смысла нет.
Событие для расширения источников скидок — пока нет реального запроса, добавим, если появится.
Activity
feat(order): clamp negative totals and Vue discount/markup badges (#265)
Merge pull request #266 from Ibochkarev/feat/gh-265-negative-total-cl…