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

Правила раздела: faq.php?mode=okay
Модератор: Модераторы

Family Mall
Family Mall
Репутация: 2
Сообщения: 42
Зарегистрирован: 04.08.2017
С нами: 6 лет 7 месяцев

Сообщение #1 Family Mall » 06.08.2019, 17:05

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

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #2 korshunov » 06.08.2019, 17:33

Стандартно такого нет.

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

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #3 makki » 07.08.2019, 07:33

Доработка не сложная. Если задавать размер скидки в зависимости от суммы заказа напрямую в базе данных, а не в админке, доработка будет состоять из добавления новой таблицы в БД и пару строчек кода.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #4 korshunov » 07.08.2019, 07:56

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

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

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

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #5 makki » 07.08.2019, 08:04

korshunov писал(а):Обычно, если надо лишь пару строк, то их просто пишут сразу - чего мелочиться-то...
В этот раз я решил написать в Вашем стиле, без кода :)
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #6 korshunov » 07.08.2019, 08:20

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

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

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

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

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

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #7 makki » 07.08.2019, 11:08

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
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #8 korshunov » 07.08.2019, 12:11

Придираться к тому, что написано не "пару строчек кода", а побольше, не будем.

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


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

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #9 makki » 07.08.2019, 13:29

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

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #10 korshunov » 08.08.2019, 11:58

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

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

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

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

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

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #11 makki » 08.08.2019, 14:39

Спасибо. У меня на рабочем сайте стоит 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));
                }
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #12 korshunov » 08.08.2019, 14:51

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

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

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #13 makki » 08.08.2019, 15:16

Не предполагал даже, что можно назначать большую скидку за меньшую сумму заказа.
Ну если так, то да, нужно ORDER BY value, только без DESC
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #14 korshunov » 08.08.2019, 16:10

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);

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #15 makki » 08.08.2019, 16:36

DESC сортировка по убыванию. Первым будет максимальная скидка, а нам надо минимальную
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #16 korshunov » 08.08.2019, 16:48

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

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

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #17 makki » 08.08.2019, 16:55

korshunov писал(а):Для случая
`value`, `min_order_price`
3 5000
5 3000
не будет минимальная скидка при заказе на сумму 8000.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #18 korshunov » 08.08.2019, 18:18

Для случая
`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%. По моему, это правильно (при действии разных акций применяется та из них, наиболее выгодная покупателю, то есть максимальная скидка).

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


Название раздела: Вопросы по работе с OkayCMS
Правила раздела: faq.php?mode=okay

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения

   

Вернуться в «Вопросы по работе с OkayCMS»

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 28 гостей