Накопительные скидки с помощью Ubercart discount alt+Rules+Ubercart rules

Главные вкладки

Аватар пользователя jchoo jchoo 29 мая 2012 в 15:58

По просьбам трудящихся выкладываю решение "Накопительные скидки для Ubercart 2".

При разработке магазина часто возникает необходимость делать скидки для покупателей. С единоразовыми скидками и купонами проблем обычно не возникает, но что делать если Вам нужны накопительные скидки?

Обсудив эту проблему со своим коллегой, покопавшись на форуме и приложив немного усилий нами было найдено вполне рабочее и удобное решение. Оно основано на присваивании определенной роли, пользователю, который оплатил покупку в нашем магазине.
Итак:

  1. Скачиваем модули Ubercart Discounts (Alternative) (для установки модуля вам так же понадобятся: Ubercart, date_popup, CCK), Rules и Uc rules.
  2. Устанавливаем их
  3. Вот тут уже интереснее.

  4. Идем в раздел Управление пользователями > Роли (/admin/user/roles) и создаем там 3 роли. Например , 10%, 15%, 20%. Сохраняем.
  5. Идем в настройки модуля Ubercart Discounts (Alternative), Управление магазином > Скидки > Добавить скидку(/admin/store/uc_discounts/add). Добавляем скидку 10% (переводы строк могут отличатся):
    • Имя > 10%
    • Короткое описание > 10%
    • Описание > 10%
    • Активна > Ставим галку
    • Может быть объединена с другими скидками > Не ставим галку
    • Скидка начнет действовать с > Не ставим галку
    • Скидка истекает > Не ставим галку
    • Вес 0
    • Квалификационный тип > Минимальная цена
    • Минимальное квалификационное значение > 1 (!)Обратите внимание, это очень важный пункт
    • Из трех следующих чек-боксов выбираем третий, квалиФикация по роли > Ставим галку
    • В ролях выбираем скидку 10%
    • Фильтр Required products не трогаем
    • Тип скидки > Процент от
    • Значение > 0.1 (тут скидка указывается в десятых долях, т.е. если Вам нужна скидка 5% указываете цифру 0.05 и т.д.)
    • Фильтр продуктов оставляем в положении "Все продукты", если хотите скидку на весь ассортимент, если нужно на отдельные продукты, то выбираем их из списка.
    • Остальные пункты оставляем как есть
    • Сохраняем

    Со скидками 15% и 20% проделываем туже самую процедуру.

  6. Идем в раздел Правила > Срабаты- ваемые правила > Добавить - правило (/admin/rules/trigger/add)
    • Метка > sale 10
    • Событие > Выбираем из списк- а > ubercart rules > order checkout complete(заказ завершен)
    • Данное правило активно и выполняется при возникновении ассоциированного события > Ставим галку > Жмем продолжить

    Описание правила:

    • ПРИ срабатывании события Order checkout complete > Выполнение php кода
    • Все поля оставляем без изменений, в поле PHP кода пишем такой код
    • <?php
      global $user;
      $user_id $user->uid;

      $result db_query("SELECT sum(order_total) FROM `uc_orders` where uid =".$user_id);

      $total = array(); 
      while(
      $value db_fetch_array($result)) {
        
      $total $value;
      }

      foreach(

      $total as $value){
      if (
      $value >= 10000 and $value 15000){ /*вот тут задаем суммы при которых будет срабатывать наша скидка, если сумма больше или равна 10 000 и меньше или равна 15 000 то пользователь получит роль 10% на для которой создана скидка 10%, для 15%-скидки, уже указываете диапазон от 15 001 до 20 000 и так далее.*/
      return 1// А вот эта единица то как раз и запустит нашу скидку, созданную в модуле скидок.
      };
      }
      ?>
    • Жмем сохранить
    • После пункта "ПРИ срабатывании события Order checkout complete" будет пункт:

    • ВЫПОЛНИТЬ > Добавить действие
    • Из списка выбираем User > add user role (Добавить роль пользователю) > Жмем далее
    • Выбираем нашу роль 10% > Жмем сохранить
    • Добавляем еще одно действие > remove user role (Удалить роль пользователя) > Жмем сохранить
    • Выбираем все оставшиеся "скидочные" роли (15% и 20%) > Жмем сохранить

    Для скидок 15% и 20% проделываем все те же действия, не забывая менять суммы скидок в PHP коде.

Комментарии

Аватар пользователя VasyOK VasyOK 10 ноября 2015 в 11:48

Делал такое с тем же набором модулей, но чуть по другому. Тоже несколько ролей.

Скидка выдается в зависимости от тотальной суммы.
Скидка 5% сумма 5000руб
Скидка 10% сумма 10000руб
Скидка 15% сумма 30000руб

Создал скидки

Сама скидка

В Rules создал запланированные правила

Для скидки в 5%
1)

2)

3)

В случае со скидкой 15% нудно удалить роли 5% и 10% у пользователя

PHP код такой

$total_sum = db_result(db_query("SELECT COALESCE(SUM(price * qty), 0) AS total FROM {uc_order_products} ucpr LEFT JOIN {uc_orders} uc ON ucpr.order_id = uc.order_id  LEFT JOIN {uc_order_statuses} ucs ON uc.order_status = ucs.order_status_id WHERE uid = %d AND state NOT IN('%s', '%s')", $user->uid, 'canceled', 'in_checkout'));

return  $total_sum > 5000 && $total_sum <= 100000;

Но есть еще клиент со скидкой 15%. Ему уже двигаться некуда. (Хотя возможно создать правило "если сумма покупки больше 1 000 000 000, клиент становится владельцем магазина")

Для него правило такое:


Код такой:

$total_sum = db_result(db_query("SELECT COALESCE(SUM(price * qty), 0) AS total FROM {uc_order_products} ucpr LEFT JOIN {uc_orders} uc ON ucpr.order_id = uc.order_id  LEFT JOIN {uc_order_statuses} ucs ON uc.order_status = ucs.order_status_id WHERE uid = %d AND state NOT IN('%s', '%s')", $user->uid, 'canceled', 'in_checkout'));

return  $total_sum > 300000;

А действия для него нет.

Код брал из модуля Order Total Discount http://drupal.org/project/uc_discount_total

А еще можно поставить модуль
price ranges field, и создать им поле в котором отображено, какая именно цена для пользователя со скидкой

Аватар пользователя VasyOK VasyOK 23 сентября 2012 в 12:24

Работа над ошибками.

Попробовал метод jchoo. Пожил не много со своим методом и хочу сказать что нашел одну особенность.
Если делать все как описано выше пользователь получит скидку после того как сделает заказ.

Т.е. пользователь:
1) делает заказ на приличную сумму
2) сообщает админу что ему это не надо
3) через неделю делает заказ на мелкую сумму, но уже являясь обладателем скидки. А за что ему скидка то?

Скидку пользователь должен получать, не после того как делает заказ, а после того как админ подтверждает заказ.

Что нужно:

Использовать в правиле (Rules) событие Order state is updated - per order line (наверное)
Условие 1. Filter order by status. Status: Complited (Завершено)
Условие 2. Выполнение PHP кода.
В коде сделать выборку из БД. "Если сумма заказов пользователя и имеющих статус Завершено больше и меньше определнного числа."

Действие 1. Load customer by order (User)
Действие 2. Изменить роль пользователя (как на скринах выше)

Буду рад если кто-то правильно напишет Условие 2. На это моих скилов не хватает.

Аватар пользователя Andruxa Andruxa 10 ноября 2015 в 11:48

"jchoo" wrote:

$result = db_query("SELECT sum(order_total) FROM `uc_orders` where uid =".$user_id);

1. У пользователя могут быть оформленные, но не оплаченные заказы, либо заказы, по которым произошли возвраты - их суммы будут учитываться в общей сумме покупок пользователя.
2. Бывает (у меня был такой случай), что заказчик хочет, чтобы общая сумма покупок считалась по товарам в оплаченных заказах, исключая стоимость доставок и прочих доп.услуг - тоже не реализовано.

За желание делиться опытом - спасибо.

UPD.
откопал и приаттачил свой модуль, которым делал накопительные скидки

Аватар пользователя VasyOK VasyOK 25 сентября 2012 в 15:47

Думаю считать по order total не совсем корректно, если есть Ubercart discount alt. При его наличии скидка (которая может быть) не попадает в переменную order total.

Аватар пользователя Andruxa Andruxa 25 сентября 2012 в 21:32

"VasyOK" wrote:
скидка (которая может быть) не попадает в переменную order total

если не ошибаюсь, скидка пишется в line item, т.е. её можно также вычитать из общей суммы, как и доставку, у меня просто не было такой задачи.

на самом деле, я против расчета общей суммы покупок за вычетом скидок, доставок и т.п., поэтому у себя в модуле делал выбор - учитывать стоимость доставки или нет

попробую объяснить на пальцах:
допустим, я сделал в магазине 3 покупки: на 1, 2 и 3 тыс.руб
правильнее сказать - я заплатил магазину 1+2+3 = 6000р. и расчитываю на накопительную скидку, которая начинается, например, от 5000р.
но продавец мне говорит: эээ нет, всё не так, первый раз ты оформил заказ на 1000р, в котором доставка составляла 300р, а стоимость товаров - 700р.
во второй - была доставка 300р. и ещё один товар был по акции, его стоимость не учитывается при расчете общей суммы покупок, и и в третий раз - то же что-то в таком роде, и получается, что общая сумма покупок - 4700р, накопительной скидки пока не будет

пусть даже все эти правила были указаны в магазине - я всё равно пошлю его подальше, ну его нафиг с таким матаном

т.е. мое мнение - чем проще и понятнее покупателю, тем лучше.

накопительную скидку стоит считать от общей суммы заказа - именно её покупатель помнит и может проверить без логарифмической линейки,
уж лучше сделать повыше пороги, при которых предоставляется очередная скидка

Аватар пользователя VasyOK VasyOK 5 октября 2012 в 0:10

Хорошо скидки можно не учитывать при рассчете общей суммы заказов.
Написал такое условие в Rules

<?php
$uload 
$user_loaded -> uid;
$total "SELECT sum(order_total) AS total FROM {drushop_uc_orders} WHERE 
uid = "
.$uload."  
AND 
order_status = '"
.completed."'";
return  
$total 100000 && $total <= 200000;
?>

Не работает, выдает:
user warning: Table 'name_of_user.uc_orders' doesn't exist query: SELECT sum(order_total) FROM `uc_orders` where uid =1 in ...modules/rules/rules/modules/php.rules.inc(88) : eval()'d code on line 5.

Что это за: Table 'name_of_user.uc_orders'

Аватар пользователя dimonx dimonx 24 января 2013 в 6:19

Скидку пользователь должен получать, не после того как делает заказ, а после того как админ подтверждает заказ.

чем решился вопрос?

Аватар пользователя dimonx dimonx 26 февраля 2013 в 9:54

В Rules добавил событие -User page has been viewed-

Выполнить PHP

<?php
$order_id 
db_result(db_query("SELECT order_id FROM {uc_orders} WHERE order_status = 'completed' AND uid = $user->uid"));
$user_status db_result(db_query("SELECT rid FROM {users_roles} WHERE uid = $user->uid"));
if (
$user_status==&& $order_id <> 0) {
db_query("UPDATE {users_roles} SET rid = 10 WHERE uid = $user->uid");
}
?>

Зарегистрированный пользователь имеет статус Покупателя. После оплаты заказа и подтверждения админом (Статус - Завершено), войдя на страницу своего аккаунта его роль становится Постоянный покупатель.

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

ps. значение rid - не забываем менять на свои... афигенско работает ))

Аватар пользователя VasyOK VasyOK 10 ноября 2015 в 11:49

dimonx, если честно, не совсем ясно. Может где-то и прогнал. Можешь свои скрины дать.
Делал так

php код в условии:

<?php
$total_sum 
db_result(db_query("SELECT COALESCE(SUM(price * qty), 0) AS total FROM {uc_order_products} ucpr LEFT JOIN {uc_orders} uc ON ucpr.order_id = uc.order_id  LEFT JOIN {uc_order_statuses} ucs ON uc.order_status = ucs.order_status_id WHERE uid = %d AND state NOT IN('%s', '%s')"$user->uid'canceled''in_checkout'));
return  
$total_sum 5000 && $total_sum <= 100000;
?>

В действии ставил как у тебя.
А в Arguments configuration нужно брать User: acting user или viewed user?

Аватар пользователя dimonx dimonx 4 марта 2013 в 11:53

Для ВИПа (общая сумма покупок => 10000) все тоже самое
код

<?php

$countrows 

db_result(db_query("SELECT SUM(order_total) FROM {uc_orders} WHERE uid = $user->uid AND order_status = 'completed'"));
$user_status db_result(db_query("SELECT rid FROM {users_roles} WHERE uid = $user->uid"));
if (
$countrows >= 10000 && $user_status >= && $user_status <=10) {
db_query("UPDATE {users_roles} SET rid = 11 WHERE uid = $user->uid");
}
?>

выбирается сумма всех ЗАВЕРШЕННЫХ заказов пользователя
проверяется что юзер имеет статус ПОСТОЯННОГО покупателя и имеет сумму ЗАВЕРШЕННЫХ >= 10000
обновляется роль

(!) ЕСЛИ (IF) - во всех случаях - пустое (!)

Аватар пользователя VasyOK VasyOK 4 марта 2013 в 13:59

Ууууу.

rid = 11 - это номер роли пользователя отсюда admin/user/roles/edit/11
А $user_status==9 это что?
У меня их 2 активен и блокирован. Они где-то выставляются?

Аватар пользователя dimonx dimonx 5 марта 2013 в 3:08

rid FROM {users_roles}
rid - столбец в таблице users_roles
в нем прописаны все роли которые созданы на сайте, каждой роли соответствует свой rid.

Аватар пользователя VasyOK VasyOK 5 марта 2013 в 9:55

Хорошо, допустим я хочу т.обр. добавить зарегистрированному пользователю роль Пользователь со скидкой 5%
В таблице users_roles у меня минимальный rid=3, в то время как в талице role для authenticated user значение rid = 2

Аватар пользователя dimonx dimonx 5 марта 2013 в 10:08

role для authenticated user это вообще не учитывается
если юзер есть в таблице users_roles, то конечно он authenticated user

какое необходимо условие на назначение Пользователь со скидкой 5% ???
какой rid Пользователь со скидкой 5% ???

Аватар пользователя dimonx dimonx 6 марта 2013 в 8:41

$countrows = db_result(db_query("SELECT SUM(order_total) FROM {uc_orders} WHERE uid = $user->uid AND order_status = 'completed'"));
$user_status = db_result(db_query("SELECT rid FROM {users_roles} WHERE uid = $user->uid"));
$user_statuss = $user_status + 1;
if ($user_statuss==1 && $countrows >= 5000) {
db_query("INSERT INTO {users_roles} (uid, rid) VALUES ($user->uid, 8)");
}

======================================
Если пользователь только зарегистрировался и не имеет никаких ролей то его нет в таблице users_roles.
Этот код проверяет: сумму всех заказов пользователя -> проверяет имеет ли он какие-то роли -> если ролей нет, а сумма завершенных больше 5000 = делаем вставку в таблицу users_roles.

Важно! Отработка кода произойдет только на странице пользовательского аккаунта.
Ограничение < 100000 - тут не нужно. Его необходимо вставлять в следующую роль (Пользователь со скидкой 10%).

Аватар пользователя VasyOK VasyOK 10 ноября 2015 в 11:49

Не работает почему-то.
Сделал правило.

Зарегистрированный юзер делает заказ, админ выставляет статус заказа как "Завершено", но юзер не переходит в следующую роль.

Аватар пользователя dimonx dimonx 7 марта 2013 в 10:44

Важно! Отработка кода произойдет только на странице пользовательского аккаунта.

войди под юзером на страницу аккаунта

Аватар пользователя VasyOK VasyOK 7 марта 2013 в 11:51

Да, действительно. Пользователь переходит на свою страничку и после этого у него меняется роль.
А зечем это?

А можно чтобы роль менялась без перехода юзера на свою страничку? Админ выставляет заказ завершенным и если сумма всех заказов юзера больше 100000, то юзер повышается в звании.

Аватар пользователя melkii1991 melkii1991 13 октября 2014 в 9:21

Добрый день, поднимаю вопрос, так как не нашел не чего на просторах интернета, мне нужная такая же фишка но на ubercart 3 и drupal 7 суть в том что! не могу понять рулес так как он стал в 7 не много другой! с ним не разу не работал! и в этом случае не могу сделать 5 пункт (из-за rules) может кто делал или кто подскажет это решение?