Модуль "Бонусный счет"

Материал из NoDeny Plus
Перейти к: навигация, поиск

Возможности

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

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

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

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

Пример:

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

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

Bonus balance.png

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

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

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

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

Имя поля     : Бонусный баланс
Имя поля в бд : _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 ;