@ssrdop

Как правильно генерировать конечную цену и строить динамические скидки?

Например у нас на сайте есть 2000 товаров.
В определенные дни, на определенные товары есть скидки.
Есть скидки в определенные часы.
Скидки на комплекты и прочее, то есть условий может быть много.
Как в плане архитектуры это все запрограммировать, чтобы легко можно было удалять, добавлять новые скидки?
Как это можно реализовать для конечного клиента в админке?
  • Вопрос задан
  • 407 просмотров
Решения вопроса 1
XXXXPro
@XXXXPro
Fullstack Web developer
Во-первых, я сделал бы интерфейс iPriceCalc, и набор классов, реализующих этот интерфейс, и все расчеты вынес бы в них. (Соответственно, в классе должен быть один метод, в который передается информация о товаре и, на всякий случай, залогиненном пользователе.) Плюс на всякий случай предусмотрел бы для каждого товара предусмотреть возможность указывать в базе, какой именно класс для расчета цены должен использоваться.
Редактор динамических скидок сделал бы так: таблица, в каждой ее строке несколько selectов. В первом из них выбираем, что именно проверяем (текущее число, текущий день недели, текущее время, цена продукта, категория и т.п.). Во втором — операция проверки (меньше, больше, равно, не равно). В третьем - значение с которым сравниваем.
В конце таблицы — размер скидки и ее тип (абсолютная в рублях или относительная в процентах).
Все это сохраняем в массив (с помощью сериализации в PHP или JSON) и передаем классу, осуществляющему расчет цены. Он проходит этот массив последовательно, берет каждую строку, подставляет вместо первого selectа реальное значение, смотрит, какую операцию нужно применить и сравнивает. Если все условия в наборе выполнились, скидка применяется и класс возвращает исправленную цену.
То есть получаем примерно такой:
class ConditionPriceCalculator implements iPriceCalc {
function calc($product,$user) {
$data = get_file_contents('файл с условиями');
$conditions = unserialize($data);
$result = true;
foreach ($conditions as $condition) {
   // в поле comp_value лежит условное значение из первого selectа, для которого нужно посчитать реальное значение
   if ($condition['comp_value']=='day') $value1==date('d');
   elseif ($condition['comp_value']=='weekday') $value1=date('N');
  // ... и так далее
  $value=$condition['value']; // тут хранится, с чем сравнивать
  if ($condition['op']=='eq') $cur_res = $value1==$value2;
  if ($condition['op']=='ne') $cur_res = $value1!=$value2;
  //  и т.д.
  if (!$cur_res) $result = false; // если условие не выполнилось, общий результат сбрасываем в false, еще можно добавить break;
}
if ($result) {
  // если все условия из набора выполнились, рассчитываем новую цену:
}
}
}

В принципе, можно предусмотреть, чтобы таких наборов условий было несколько и применялся первый сработавший.
Единственное ограничение — это то, что нельзя в одном наборе условий объединять их по "ИЛИ", а не по "И".
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы