Проблема
После #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 — естественный способ выразить наценку/скидку, ломать его смысла нет.
- Событие для расширения источников скидок — пока нет реального запроса, добавим, если появится.
Связанные
Проблема
После #211 / #246 поле
priceу способов доставки и оплаты поддерживает отрицательные значения и проценты — это позволяет настраивать скидки за способ оплаты/доставки (например, «−5% за оплату наличными», «−200₽ за самовывоз»).Текущая реализация оставляет два открытых вопроса:
Нет защиты от отрицательного
totalзаказа.isAllowedPercentограничивает только проценты диапазоном-100..100, а фиксированная скидка вроде-99999сохранится без вопросов. При накоплении скидок из нескольких источников (доставка + оплата)totalможет уйти в минус. Потенциальный фрод-вектор.UX в админке не различает наценку и скидку. Поле одно, plain textfield, подсказка в lexicon говорит «может быть отрицательной». Оператор легко теряет знак при копи-пасте или вводе с клавиатуры и продаёт в минус.
Предложение
1. Защита
totalвOrderService::recalculate()Финальная проверка после применения всех слагаемых:
Записывать в лог все слагаемые, чтобы при ручном разборе было видно, какая настройка увела заказ в минус.
2. UX-маркер «Скидка / Наценка» в админке
В Vue-формах способов доставки и оплаты рядом с полем
price:-→ зелёный бейдж «Скидка».0или пусто → без бейджа.Реактивная подсказка по
v-modelполя, без серверной валидации. Помогает оператору сразу видеть знак.Из scope намеренно вынесено
discountна моделях — не нужно. Знак числа вprice— естественный способ выразить наценку/скидку, ломать его смысла нет.Связанные