Модуль "Бонусный счет": відмінності між версіями

Матеріал з NoDeny
Перейти до навігації Перейти до пошуку
Немає опису редагування
 
(Не показано 20 проміжних версій цього користувача)
Рядок 4: Рядок 4:


* Услуга, которая при завершении пополняет основной и/или бонусный счет
* Услуга, которая при завершении пополняет основной и/или бонусный счет
* Отдельный бонусный счет. При пополнении основного счета, с бонусного, если на нем достаточно финансов, на основной счет будет переведена сумма, эквивалентная пополнению.
* При пополнении основного счета, с бонусного, если на нем достаточно финансов, на основной счет будет переведена сумма, эквивалентная пополнению.


==Бонусная услуга==
==Бонусная услуга==
Может быть применена в акциях «Пополни счет на 100$ и через 3 месяца на счет будет зачислено 110$» или «Пополни счет на 100$ и через 3 месяца на счет будет зачислено 100$, а на бонусный счет 10$».
Может быть применена в акциях «Пополни счет на 100$ и через 3 месяца будет зачислено 110$» или «Пополни счет на 100$ и через 3 месяца будет зачислено 100$, а на бонусный счет 10$».


Пример:
Пример:
Рядок 13: Рядок 13:
* Абонент пополняет счет на 100$
* Абонент пополняет счет на 100$
* Баланс увеличивается на 100$
* Баланс увеличивается на 100$
* Подключает услугу «Пополни счет на 100$ и через 3 месяца на счет будет зачислено 110$»
* Подключает услугу «Депозит» с описанием «Пополни счет на 100$ и через 3 месяца будет зачислено 110$»
* Со счета списывается 100$
* Со счета списывается 100$
* Через 3 месяца завершается услуга и основной счет пополняется на 100$, а бонусный на 10$
* Через 3 месяца завершается услуга и основной счет пополняется на 110$


Естественно, все параметры (деньги, время, комментарий) настраиваемы.
Естественно, все параметры (деньги, время, комментарий) настраиваемы:


[[Файл:Bonus_balance.png|700px]]
[[Файл:Bonus_balance.png|700px]]
При настройке услуги поставьте галку «Запретить клиентам продлевать эту услугу».
 
При настройке услуги поставьте галку «Запретить клиентам продлевать эту услугу» чтобы при переустановке услуги она не замораживалась когда включена такая фича.


Обратите внимание, после подключения услуги, деньги как бы резервируются и абонент не сможет ими распоряжаться.
Обратите внимание, после подключения услуги, деньги как бы резервируются и абонент не сможет ими распоряжаться.
Рядок 33: Рядок 34:
Тип поля      : деньги
Тип поля      : деньги
</pre>
</pre>
==Автоматический  перевод финансов с бонусного на основной счет при пополнении==


Создайте услугу типа «Бонус при завершении»:
Создайте услугу типа «Бонус при завершении»:


<pre>
<pre>
Имя услуги: С бонусного на основной
Имя услуги: С бонусного на основной (можно иное название)
Стоимость: неважно (использоваться не будет)
Стоимость: неважно (использоваться не будет)
Описание, которое будут видеть клиенты: Перевод с бонусного счета на основной (это будет в комментарии бонусного платежа)
Описание, которое будут видеть клиенты: неважно (использоваться не будет)
Автопродление: не ставим галку
Автопродление: не ставим галку
Запрет продления: ставим галку
Запрет продления: ставим галку
Группы: не ставим ни одной галки!
Группы: не ставим ни одной галки!
Сумма: неважно (использоваться не будет)
Пополнение основного счета: неважно (вычисляется динамически)
Комментарий к пополнению (основного счета): «перевод бонусов на основной счет»
Пополнение бонусного счета: неважно (использоваться не будет)
Комментарий к пополнению (бонусного счета): неважно (использоваться не будет)
Режим: неважно (использоваться не будет)
Режим: неважно (использоваться не будет)
Срок действия: неважно (использоваться не будет)
Срок действия: неважно (устанавливается mysql процедурой)
</pre>
</pre>


Рядок 55: Рядок 61:
CREATE TRIGGER tr_bb_pays_insert AFTER INSERT ON pays
CREATE TRIGGER tr_bb_pays_insert AFTER INSERT ON pays
     FOR EACH ROW
     FOR EACH ROW
     IF NEW.mid > 0 AND NEW.cash > 0 AND NEW.category <> 2 THEN
     IF NEW.mid > 0 AND NEW.cash > 0 AND NEW.category NOT IN (2, 3) THEN
    BEGIN
        DECLARE money FLOAT;
        SELECT CAST(IF(_bonus_balance >= NEW.cash, NEW.cash, _bonus_balance) AS DECIMAL(10,2)) INTO money
            FROM data0 WHERE uid = NEW.mid LIMIT 1;
        IF money > 0 THEN
            BEGIN
                UPDATE data0 SET _bonus_balance = CAST(_bonus_balance - money AS DECIMAL(10,2))
                    WHERE uid = NEW.mid LIMIT 1;
                INSERT INTO users_services SET uid=NEW.mid, service_id=98, next_service_id=0,
                    pay_id=0, tm_start=UNIX_TIMESTAMP(), tm_end=UNIX_TIMESTAMP()+2,
                    tags=CONCAT(',main_money=', money, ',');
            END;
        END IF;
    END;
    END IF;
$$
DELIMITER ;
 
 
DROP TRIGGER IF EXISTS `tr_bb_pays_update`;
 
DELIMITER $$
CREATE TRIGGER tr_bb_pays_update AFTER UPDATE ON pays
    FOR EACH ROW
    IF NEW.mid > 0 AND NEW.cash > 0 AND NEW.category NOT IN (2, 3) AND OLD.category IN (444, 445) THEN
     BEGIN
     BEGIN
         DECLARE money FLOAT;
         DECLARE money FLOAT;
         SELECT IF(_bonus_balance >= NEW.cash, NEW.cash, _bonus_balance) INTO money
         SELECT CAST(IF(_bonus_balance >= NEW.cash, NEW.cash, _bonus_balance) AS DECIMAL(10,2)) INTO money
             FROM data0 WHERE uid = NEW.mid LIMIT 1;
             FROM data0 WHERE uid = NEW.mid LIMIT 1;
         IF money > 0 THEN
         IF money > 0 THEN
             BEGIN
             BEGIN
                 UPDATE data0 SET _bonus_balance = _bonus_balance - money WHERE uid = NEW.mid LIMIT 1;
                 UPDATE data0 SET _bonus_balance = CAST(_bonus_balance - money AS DECIMAL(10,2))
                    WHERE uid = NEW.mid LIMIT 1;
                 INSERT INTO users_services SET uid=NEW.mid, service_id=98, next_service_id=0,
                 INSERT INTO users_services SET uid=NEW.mid, service_id=98, next_service_id=0,
                     pay_id=0, tm_start=UNIX_TIMESTAMP(), tm_end=UNIX_TIMESTAMP()+2,
                     pay_id=0, tm_start=UNIX_TIMESTAMP(), tm_end=UNIX_TIMESTAMP()+2,
Рядок 73: Рядок 105:
DELIMITER ;
DELIMITER ;
</pre>
</pre>
В этом sql нужно в service_id=98 число 98 заменить на id услуги, что мы создали выше.


==Тестирование==
==Тестирование==
Рядок 95: Рядок 129:


Обратите внимание, что бонусный счет уменьшается в триггере. А основной пополняется именно при завершении услуги.
Обратите внимание, что бонусный счет уменьшается в триггере. А основной пополняется именно при завершении услуги.
==Вывод бонусного счета в личном кабинете==
Бонусный счет - это дополнительное поле с именем _bonus_balance. Чтобы вывести его значение в личном кабинете, нужно найти соответствующий шаблон и в нужное место вставить вывод значения поля _bonus_balance. Чтобы вы понимали, что будете делать, рекомендуется прочитать:
*[[Переменные шаблона личного кабинета|Какие переменные есть и как их выводить]]
*[[Дизайн личного кабинета]]
После прочтения документации по переменным, становится ясно, что баланс можно вывести таким образом:
<pre>
{{ user_info.dopdata._bonus_balance.show() }}
</pre>
Из документации по изменению дизайна личного кабинета становится ясно, что не нужно менять файлы с шаблонами, а следует скопировать нужный шаблон в раздел «Документы» и уже там сделать изменения. Если мы хотим, чтобы баланс отображался на всех страницах личного кабинета, нужно править общий шаблон:
<pre>
cat /usr/local/nodeny/web/tmpl/user/base.html
</pre>
Скопируйте весь текст из этого файла. В разделе «Документы» создайте папку с именем «Кабинет клиента». Справа в поле «теги» обязательно введите system. В папке «Кабинет клиента» создайте документ с именем «Base» и установите ему теги:
<pre>
system
template=base
role=user
</pre>
Вставьте содержимое файла /usr/local/nodeny/web/tmpl/user/base.html. При этом в тексте после
<pre>
&lt;div id='main_block_header'&gt;
</pre>
вставьте следующее:
<pre>
Бонусный баланс: <span>{{ user_info.dopdata._bonus_balance.show() }} {{cfg::gr}}</span>
</pre>
==Автоматическое сообщение абоненту о пополнении бонусного счета==
<pre>
DROP TRIGGER IF EXISTS `tr_bb_data0_update`;
DELIMITER $$
CREATE TRIGGER tr_bb_data0_update AFTER UPDATE ON data0
    FOR EACH ROW
    IF CAST(NEW._bonus_balance AS DECIMAL(10,2)) > CAST(OLD._bonus_balance AS DECIMAL(10,2)) THEN
    BEGIN
        INSERT INTO pays SET cash=0, category=480, reason='', creator='other', creator_ip=0, creator_id=0,
            time=UNIX_TIMESTAMP(), mid=NEW.uid, comment=
            CONCAT(
                'Бонусный счет пополнен на ',
                CAST(CAST(NEW._bonus_balance AS DECIMAL(10,2)) -
                    CAST(OLD._bonus_balance AS DECIMAL(10,2)) AS DECIMAL(10,2)),
                ' грн. Остаток на бонусном счете ',
                NEW._bonus_balance,
                ' грн.'
            );
    END;
    END IF;
$$
DELIMITER ;
</pre>

Поточна версія на 19:51, 20 серпня 2019

Возможности

Модуль добавляет в биллинг 2 фичи (могут быть задействованы как обе, так и только одна):

  • Услуга, которая при завершении пополняет основной и/или бонусный счет
  • При пополнении основного счета, с бонусного, если на нем достаточно финансов, на основной счет будет переведена сумма, эквивалентная пополнению.

Бонусная услуга

Может быть применена в акциях «Пополни счет на 100$ и через 3 месяца будет зачислено 110$» или «Пополни счет на 100$ и через 3 месяца будет зачислено 100$, а на бонусный счет 10$».

Пример:

  • Абонент пополняет счет на 100$
  • Баланс увеличивается на 100$
  • Подключает услугу «Депозит» с описанием «Пополни счет на 100$ и через 3 месяца будет зачислено 110$»
  • Со счета списывается 100$
  • Через 3 месяца завершается услуга и основной счет пополняется на 110$

Естественно, все параметры (деньги, время, комментарий) настраиваемы:

При настройке услуги поставьте галку «Запретить клиентам продлевать эту услугу» чтобы при переустановке услуги она не замораживалась когда включена такая фича.

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

Бонусный счет

Создайте дополнительное поле:

Имя поля     : Бонусный баланс
Имя поля в бд : _bonus_balance
Тип поля      : деньги

Автоматический перевод финансов с бонусного на основной счет при пополнении

Создайте услугу типа «Бонус при завершении»:

Имя услуги: С бонусного на основной (можно иное название)
Стоимость: неважно (использоваться не будет)
Описание, которое будут видеть клиенты: неважно (использоваться не будет)
Автопродление: не ставим галку
Запрет продления: ставим галку
Группы: не ставим ни одной галки!
Пополнение основного счета: неважно (вычисляется динамически)
Комментарий к пополнению (основного счета): «перевод бонусов на основной счет»
Пополнение бонусного счета: неважно (использоваться не будет)
Комментарий к пополнению (бонусного счета): неважно (использоваться не будет)
Режим: неважно (использоваться не будет)
Срок действия: неважно (устанавливается mysql процедурой)

В mysql:

DROP TRIGGER IF EXISTS `tr_bb_pays_insert`;

DELIMITER $$
CREATE TRIGGER tr_bb_pays_insert AFTER INSERT ON pays
    FOR EACH ROW
    IF NEW.mid > 0 AND NEW.cash > 0 AND NEW.category NOT IN (2, 3) THEN
    BEGIN
        DECLARE money FLOAT;
        SELECT CAST(IF(_bonus_balance >= NEW.cash, NEW.cash, _bonus_balance) AS DECIMAL(10,2)) INTO money
            FROM data0 WHERE uid = NEW.mid LIMIT 1;
        IF money > 0 THEN
            BEGIN
                UPDATE data0 SET _bonus_balance = CAST(_bonus_balance - money AS DECIMAL(10,2))
                    WHERE uid = NEW.mid LIMIT 1;
                INSERT INTO users_services SET uid=NEW.mid, service_id=98, next_service_id=0,
                    pay_id=0, tm_start=UNIX_TIMESTAMP(), tm_end=UNIX_TIMESTAMP()+2,
                    tags=CONCAT(',main_money=', money, ',');
            END;
        END IF;
    END;
    END IF;
$$
DELIMITER ;


DROP TRIGGER IF EXISTS `tr_bb_pays_update`;

DELIMITER $$
CREATE TRIGGER tr_bb_pays_update AFTER UPDATE ON pays
    FOR EACH ROW
    IF NEW.mid > 0 AND NEW.cash > 0 AND NEW.category NOT IN (2, 3) AND OLD.category IN (444, 445) THEN
    BEGIN
        DECLARE money FLOAT;
        SELECT CAST(IF(_bonus_balance >= NEW.cash, NEW.cash, _bonus_balance) AS DECIMAL(10,2)) INTO money
            FROM data0 WHERE uid = NEW.mid LIMIT 1;
        IF money > 0 THEN
            BEGIN
                UPDATE data0 SET _bonus_balance = CAST(_bonus_balance - money AS DECIMAL(10,2))
                    WHERE uid = NEW.mid LIMIT 1;
                INSERT INTO users_services SET uid=NEW.mid, service_id=98, next_service_id=0,
                    pay_id=0, tm_start=UNIX_TIMESTAMP(), tm_end=UNIX_TIMESTAMP()+2,
                    tags=CONCAT(',main_money=', money, ',');
            END;
        END IF;
    END;
    END IF;
$$
DELIMITER ;

В этом sql нужно в service_id=98 число 98 заменить на id услуги, что мы создали выше.

Тестирование

  • В настройках абонента устанавливаем поле «Бонусный баланс», например, в 10$
  • Пополняем счет любым небонусным платежом на 2$
  • Основной баланс увеличится на 2$
  • Бонусный счет уменьшится на 2$
  • Через несколько секунд основной баланс увеличится еще на 2$
  • Появится бонусный платеж на 2$ с комментарием про перевод денег с бонусного на основной счет

Проверка, что с бонусного не спишется больше чем на нем есть:

  • Создаем платеж на 10$
  • Баланс увеличится на 10 + 8, а на бонусном счете станет 0$
  • Дальнейшие любые пополнения не будут менять бонусный счет и пополнять основной баланс бонусами т.к на бонусном счете будет 0

Обратите внимание, что ядро должно быть запущено с модулем услуг services, хотя скорее всего он запущен ибо это один из основных модулей в NoDeny.

Принцип работы

В mysql создается триггер, который реагирует на создание записей в таблице платежей (pays). Это означает, что неважно как пополняется счет, хоть через платежную систему, хоть карточкой пополнения - триггер это «увидит»‎, подключит услугу перевода баланса (с длительностью 2 секунды), а также уменьшит бонусный счет.

Обратите внимание, что бонусный счет уменьшается в триггере. А основной пополняется именно при завершении услуги.

Вывод бонусного счета в личном кабинете

Бонусный счет - это дополнительное поле с именем _bonus_balance. Чтобы вывести его значение в личном кабинете, нужно найти соответствующий шаблон и в нужное место вставить вывод значения поля _bonus_balance. Чтобы вы понимали, что будете делать, рекомендуется прочитать:

После прочтения документации по переменным, становится ясно, что баланс можно вывести таким образом:

{{ user_info.dopdata._bonus_balance.show() }}

Из документации по изменению дизайна личного кабинета становится ясно, что не нужно менять файлы с шаблонами, а следует скопировать нужный шаблон в раздел «Документы» и уже там сделать изменения. Если мы хотим, чтобы баланс отображался на всех страницах личного кабинета, нужно править общий шаблон:

cat /usr/local/nodeny/web/tmpl/user/base.html

Скопируйте весь текст из этого файла. В разделе «Документы» создайте папку с именем «Кабинет клиента». Справа в поле «теги» обязательно введите system. В папке «Кабинет клиента» создайте документ с именем «Base» и установите ему теги:

system
template=base
role=user

Вставьте содержимое файла /usr/local/nodeny/web/tmpl/user/base.html. При этом в тексте после

<div id='main_block_header'>

вставьте следующее:

Бонусный баланс: <span>{{ user_info.dopdata._bonus_balance.show() }} {{cfg::gr}}</span>


Автоматическое сообщение абоненту о пополнении бонусного счета

DROP TRIGGER IF EXISTS `tr_bb_data0_update`;

DELIMITER $$
CREATE TRIGGER tr_bb_data0_update AFTER UPDATE ON data0
    FOR EACH ROW
    IF CAST(NEW._bonus_balance AS DECIMAL(10,2)) > CAST(OLD._bonus_balance AS DECIMAL(10,2)) THEN
    BEGIN
        INSERT INTO pays SET cash=0, category=480, reason='', creator='other', creator_ip=0, creator_id=0,
            time=UNIX_TIMESTAMP(), mid=NEW.uid, comment=
            CONCAT(
                'Бонусный счет пополнен на ',
                CAST(CAST(NEW._bonus_balance AS DECIMAL(10,2)) -
                    CAST(OLD._bonus_balance AS DECIMAL(10,2)) AS DECIMAL(10,2)),
                ' грн. Остаток на бонусном счете ',
                NEW._bonus_balance,
                ' грн.'
            );
    END;
    END IF;
$$
DELIMITER ;