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

Матеріал з NoDeny
Перейти до навігації Перейти до пошуку

Возможности

Модуль добавляет в биллинг 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 ;