Страница 1 из 1

Автоматическая скидка при покупке товара от - 100 у.е.

Добавлено: 06.08.2019, 17:05
Family Mall
Подскажите пожалуйста, может кто поможет с проблемой?! Не могу понять, где задать значение? как сделать автоматическую скидку при покупке от определенной суммы?

Добавлено: 06.08.2019, 17:33
korshunov
Стандартно такого нет.

https://okay-cms.com/products/skidka-ot-summy-zakaza

Добавлено: 07.08.2019, 07:33
makki
Доработка не сложная. Если задавать размер скидки в зависимости от суммы заказа напрямую в базе данных, а не в админке, доработка будет состоять из добавления новой таблицы в БД и пару строчек кода.

Добавлено: 07.08.2019, 07:56
korshunov
makki писал(а):Доработка не сложная. Если задавать размер скидки в зависимости от суммы заказа напрямую в базе данных, а не в админке, доработка будет состоять из добавления новой таблицы в БД и пару строчек кода.

Очень интересно.
Что-то мне подсказывает, что потом надо будет еще пару строк кода, потом еще пяток и т.д. То есть пойдет по сюжету старинной сказки "Как солдат из топора кашу варил".

Обычно, если надо лишь пару строк, то их просто пишут сразу - чего мелочиться-то...

Добавлено: 07.08.2019, 08:04
makki
korshunov писал(а):Обычно, если надо лишь пару строк, то их просто пишут сразу - чего мелочиться-то...
В этот раз я решил написать в Вашем стиле, без кода :)

Добавлено: 07.08.2019, 08:20
korshunov
makki писал(а):
korshunov писал(а):Обычно, если надо лишь пару строк, то их просто пишут сразу - чего мелочиться-то...
В этот раз я решил написать в Вашем стиле, без кода :)

Это Вы сами приписываете мне стиль страннный и несоответствующий. Тогда как про общепринятый стиль, которого и я придерживаюсь, мной написано четко: "если надо лишь пару строк, то их просто пишут сразу".

Вот пара примеров моего стиля
viewtopic.php?f=10&t=1216&p=5996#p5996
viewtopic.php?f=9&t=1268&p=6140#p6140

Если Вам он нравится, то придерживались бы его по сути, а не по формальным признакам. Спрашивающему пользы больше было бы...

В цитированной вначале разработке от маркетплейса, насколько я понимаю, не считая админки, изменения в 5-6 файлах делаются. Поэтому мне удивительно и страшно интересно, как это все сократится до двух строк в гениальном решении...

Добавлено: 07.08.2019, 11:08
makki
korshunov писал(а):В цитированной вначале разработке от маркетплейса, насколько я понимаю, не считая админки, изменения в 5-6 файлах делаются. Поэтому мне удивительно и страшно интересно, как это все сократится до двух строк в гениальном решении...
Ничего гениального.
1) Создаем новую таблицу и добавляем напрямую в поле value - процентную скидку, min_order_price - минимальная сумма заказа, от которой работает эта скидка

Код: Выделить всё

CREATE TABLE `ok_discounts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `value` float(10,2) NOT NULL,
  `min_order_price` float(10,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


2) В файле api/Cart.php после строк

Код: Выделить всё

// Пользовательская скидка
                $cart->discount = 0;
                if(isset($_SESSION['user_id']) && $user = $this->users->get_user(intval($_SESSION['user_id']))) {
                    $cart->discount = $user->discount;
                }

добавляем

Код: Выделить всё

// Разовая скидка от суммы заказа
                $sum_discount = 0;
                $this->db->query("SELECT * FROM __discounts");
                foreach($this->db->results() as $discount) {
                    if($cart->total_price >= $discount->min_order_price) {
                        $sum_discount = $discount->value;
                    }
                }

                // Максимальная из скидок
                $cart->discount = max ($cart->discount, $sum_discount);


И еще в файле шаблона design/okay_shop/html/cart_purchases.tpl нужно поменять в 2-х местах $user->discount на $cart->discount

Добавлено: 07.08.2019, 12:11
korshunov
Придираться к тому, что написано не "пару строчек кода", а побольше, не будем.

По существу:
1. А вот работать будет не всегда правильно. Если скидка применима к двум (или нескольким) правилам из таблицы, то будет применена из одна довольно случайная. А надо бы максимальную...
2. На стр корзины и заказа будет показывать в % скидку разную при разных суммах заказа, узнать пользователю, что и почему, практически невозможно. Надо бы инфу давать покупателю - за что дана скидка.
3. В письмах о заказе то же самое - написано Скидка - и все.
4. При корректировке заказа из админки, кажется, скидка новая уже правильно учитываться не будет - или будет?


Если (несложно) поправить п.1, то работать будет, но уж очень формально и некомфортно как покупателю, так и админу.

Добавлено: 07.08.2019, 13:29
makki
korshunov, я потрудился написать для вас и автора темы готовое и проверенное решение, а вы начинаете искать недостатки, поленившись проверить.
Все корректно работает.
korshunov писал(а):1. А вот работать будет не всегда правильно. Если скидка применима к двум (или нескольким) правилам из таблицы, то будет применена из одна довольно случайная. А надо бы максимальную...
Будет взята как раз максимальная
korshunov писал(а):2. На стр корзины и заказа будет показывать в % скидку разную при разных суммах заказа, узнать пользователю, что и почему, практически невозможно. Надо бы инфу давать покупателю - за что дана скидка.
3. В письмах о заказе то же самое - написано Скидка - и все.
Да, будет написано просто Скидка.
korshunov писал(а):4. При корректировке заказа из админки, кажется, скидка новая уже правильно учитываться не будет - или будет?
При редактировании заказа в админке, в стандартном функционале скидка не подтягивается с БД по условию, а передается методом POST из заполненного поля input.

Добавлено: 08.08.2019, 11:58
korshunov
1.
makki писал(а): начинаете искать недостатки, поленившись проверить...
Будет взята как раз максимальная

Как раз проверил. И думаю, куда более тщательно, чем Вы...

Почему считаете, что будет максимальная?
Если запрос выдаст из таблицы. допустим
`value`, `min_order_price`
7 5000
4 3000,
а стоимость заказа 8000, то как раз вместо большей скидки получится меньшая - по последней подходящей под условия записи.
В запросе сортировка не задана. поэтому в каком порядке выйдут записи, неизвестно. По моим наблюдениям, порядок в таких случаях довольно случаен, зависит и от истории формирования таблицы и от версии Mysql и от настроек Mysql.

Вот если запрос изменить, например, на
$this->db->query("SELECT * FROM __discounts ORDER BY value");
тогда и будет максимальная.

А еще лучше бы запрос поэкономней составить, чтоб возвращал сразу ОДНУ нужную запись...

Добавлено: 08.08.2019, 14:39
makki
Спасибо. У меня на рабочем сайте стоит ORDER BY, но в инструкции почему-то решил убрать. В любом случае вы натолкнули меня на более экономный код. В пункте 2 вместо указанного кода, нужно сделать так:

Код: Выделить всё

// Разовая скидка от суммы заказа
                $query = $this->db->placehold("SELECT value FROM __discounts WHERE min_order_price <= ? ORDER BY min_order_price DESC LIMIT 1", $cart->total_price);
                $this->db->query($query);
                if($sum_discount = $this->db->result('value')) {
                    // Максимальная из скидок
                    $cart->discount = max ($cart->discount, floatval($sum_discount));
                }

Добавлено: 08.08.2019, 14:51
korshunov
Для случая
`value`, `min_order_price`
3 5000
5 3000
не будет минимальная скидка при заказе на сумму 8000.
Надо бы 'ORDER BY value DESC LIMIT 1'.

А с неудобствами пунктов 2,3 видно, придется примириться пользователям Вашего решения...

Добавлено: 08.08.2019, 15:16
makki
Не предполагал даже, что можно назначать большую скидку за меньшую сумму заказа.
Ну если так, то да, нужно ORDER BY value, только без DESC

Добавлено: 08.08.2019, 16:10
korshunov
makki писал(а):Не предполагал даже, что можно назначать большую скидку за меньшую сумму заказа.
Ну если так, то да, нужно ORDER BY value, только без DESC

На то и специалист-программист, чтоб мыслить шире и предусматривать как можно больше "защиты от дураков".

Говорят, в Европе есть на полном серьезе банковские вклады с отрицательными процентами. А уже пользователи тем более могут и отрицательный процент написать в таблицу - тоже хорошо бы учесть... А может, это и смысл имеет - при малой сумме заказа делать скидку отрицательной, то есть надбавку к стоимости...

По-моему, надо именно с DESC:
$query = $this->db->placehold("SELECT value FROM __discounts WHERE min_order_price <= ? ORDER BY value DESC LIMIT 1", $cart->total_price);

Добавлено: 08.08.2019, 16:36
makki
DESC сортировка по убыванию. Первым будет максимальная скидка, а нам надо минимальную

Добавлено: 08.08.2019, 16:48
korshunov
makki писал(а):DESC сортировка по убыванию. Первым будет максимальная скидка, а нам надо минимальную

Зачем же нам минимальную? Обычно у магазинов порядок такой - если покупка попадает под действие разных акций, то применяется одна из них, наиболее выгодная покупателю...

Добавлено: 08.08.2019, 16:55
makki
korshunov писал(а):Для случая
`value`, `min_order_price`
3 5000
5 3000
не будет минимальная скидка при заказе на сумму 8000.

Добавлено: 08.08.2019, 18:18
korshunov
Для случая
`value`, `min_order_price`
3 5000
5 3000

при применении запроса
$this->db->placehold("SELECT value FROM __discounts WHERE min_order_price <= ? ORDER BY value DESC LIMIT 1", $cart->total_price);
Найдется одна запись 5 3000, скидка составит 5%. По моему, это правильно (при действии разных акций применяется та из них, наиболее выгодная покупателю, то есть максимальная скидка).

Не очень понимаю, зачем Вы вообще завели разговор про минимальную скидку - она тут никаким боком, по-моему...