Начисление абонплат по схеме 15-15
Материал из BiTel WiKi
Получение стоимости планируемой наработки
Доступно с версии 6.1.
Алгоритм распишем на примере. Режим снятия - подневной до текущего дня. Предположим тариф 660 рублей, делим на 30 дней получается 22 руб. в день, списывается ежедневно.
Когда клиент подключается, он должен положить сумму, равную месячной абонплате. Далее, он может пополнять свой баланс любой суммой - хоть 10 руб, хоть 100 руб - не важно. Главное, чтобы у него хватало денег на оплату интернета за день. Когда денег становится недостаточно, статус договора становится закрытый, и абонент должен положить на счет сумму, равную абонплате(660), либо большую. При это учитывается баланс договора(если у него на балансе есть 10 рублей, а абонплата за месяц 660, то клиенту для разблокировки надо заплатить 650).
Это реализовано скриптом на событие ""Запрос доп. расхода для открытия договора".
Скрипт берет планируемую наработку ( если отрыть статус с сегодняшнего дня) planAccount, фактическую наработку ( с начала месяца) currentAccount.
Вычисляется разница planAccount - currentAccount = daySumm - это и сумма которая списывается за один день(22 рубля). Далее вы умножаете эту сумму на 30. И получаем summaForUnllock - 660. сумма для разблокировки. При этом еще отнимается баланс, если там есть 10 рублей , то нужно платить 650 рублей.
Это простой вариант решения задачи, тут не учитывается смена тарифов, статусы "приостановлен" в будущем.
Скрипт на событие "Запрос доп. расхода для открытия договора".
package ru.bitel.npay.debet.test; import java.math.BigDecimal; import ru.bitel.bgbilling.kernel.event.Event; import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase; import ru.bitel.bgbilling.server.util.Setup; import ru.bitel.common.sql.ConnectionSet; import ru.bitel.bgbilling.modules.npay.server.bean.event.DebetStatusManageOpenGetAdditionalCharge; public class GetSummaForUnlock extends EventScriptBase<DebetStatusManageOpenGetAdditionalCharge> { @Override public void onEvent( DebetStatusManageOpenGetAdditionalCharge event, Setup setup, ConnectionSet connectionSet ) throws Exception { print ( "get additional charge" ); BigDecimal planAccount = event.getPlanAccount(); BigDecimal currentAccount = event.getCurrentAccount(); BigDecimal balance = event.getCurrentBalance(); BigDecimal limit = event.getLimit(); print( "currentAccount: " + currentAccount + "; planAccount: " + planAccount +"; currentBalance: " + balance + "; currentLimit: " + limit ); BigDecimal result = planAccount.subtract( currentAccount).multiply( new BigDecimal( 30 ) ).subtract( balance.subtract( limit) ) ; //BigDecimal result = planAccount.subtract( currentAccount).multiply( new BigDecimal( 29 ) ); print( "result = " + result ); event.setMode( DebetStatusManageOpenGetAdditionalCharge.MODE_REPLACE); //event.setMode( DebetStatusManageOpenGetAdditionalCharge.MODE_ADD); event.setSumma( result ); } }
Получение стоимости тарифного плана из названия тарифа и меток
В моем "частном" случае была необходимость вычислять сумму тарифного плана и в случае попадания договора в финансовую блокировку - требование всей суммы тарифного плана для разблокировки договора.
Я добавил несколько тарифных меток, которые привязал к тем тарифам за которые необходимо требовать доп. расход для открытия.
В наименование всех тарифных планов была добавлена информация о стоимости тарифа (обязательно через знак равенства, т.к. по нему идет поиск в скрипте)
Онлайн 1000 ( Днем - 60Мбит/с, Ночью - 80Мбит/с.) (Стоимость = 1000 руб./мес)
и так же каждому тарифу были присвоены добавленные метки. Для тарифа выше были установлены метки "Помесячный тариф" и "Требование доп. расхода"
Затем на событие "Запрос доп. расхода для открытия договора" был повешен следующий скрипт. Обратите внимание, что для подневных тарифов (например 10 рублей за сутки), идет умножение на 30.
package ru.ellcom.bgbilling.scripts.tariff; import bitel.billing.server.contract.bean.*; import ru.bitel.bgbilling.kernel.event.Event; import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase; import ru.bitel.bgbilling.kernel.tariff.common.bean.TariffPlan; import ru.bitel.bgbilling.kernel.tariff.server.bean.TariffLabelManager; import ru.bitel.bgbilling.kernel.tariff.server.bean.TariffPlanManager; import ru.bitel.bgbilling.modules.npay.server.bean.event.DebetStatusManageOpenGetAdditionalCharge; import ru.bitel.bgbilling.server.util.Setup; import ru.bitel.common.Utils; import ru.bitel.common.sql.ConnectionSet; import java.math.BigDecimal; import java.sql.Connection; import java.util.Date; import java.util.List; import java.util.Set; public class GetAdditionalCharge extends EventScriptBase<DebetStatusManageOpenGetAdditionalCharge> { private static int LABEL_GET_ADD_CHARGE = 84; private static int LABEL_DAY_TARIFF = 86; private static int LABEL_MONTH_TARIFF = 85; @Override public void onEvent(DebetStatusManageOpenGetAdditionalCharge event, Setup setup, ConnectionSet connectionSet) throws Exception { Connection con = connectionSet.getConnection(); ContractTariffManager ctm = new ContractTariffManager(con); ContractManager cm = new ContractManager(con); TariffPlanManager tpm = new TariffPlanManager(con); TariffLabelManager tariffLabelManager = new TariffLabelManager(con); BalanceUtils bu = new BalanceUtils(con); int cid = event.getContractId(); Date nowDate = new Date(); Contract contract = cm.getContractById(cid); BigDecimal result = BigDecimal.ZERO; BigDecimal currentBalance = bu.getBalance(nowDate, contract); BigDecimal currentLimit = contract.getBalanceLimit(); result = currentBalance.subtract(currentLimit).negate(); BigDecimal tariffPrice = BigDecimal.ZERO; List<ContractTariff> contractTariffs = ctm.getContractTariffList(cid, nowDate); for (ContractTariff ct : contractTariffs) { TariffPlan tp = tpm.getTariffPlan(ct.getTariffPlanId()); Set<Integer> tariffLabelSet = tariffLabelManager.getTariffLabelIds(tp.getId()); if (tariffLabelSet.contains(LABEL_GET_ADD_CHARGE)) { String tpTitle = tp.getTitle().substring(tp.getTitle().indexOf("=")); if (tariffLabelSet.contains(LABEL_DAY_TARIFF)) { tariffPrice = tariffPrice.add(Utils.parseBigDecimal(tpTitle.replaceAll("[^0-9]", ""), BigDecimal.ZERO)); tariffPrice = tariffPrice.multiply(new BigDecimal(30.0)); } if (tariffLabelSet.contains(LABEL_MONTH_TARIFF)) { tariffPrice = tariffPrice.add(Utils.parseBigDecimal(tpTitle.replaceAll("[^0-9]", ""), BigDecimal.ZERO)); } } if (tariffPrice.compareTo(BigDecimal.ZERO) > 0) { result = result.add(tariffPrice); event.setMode(DebetStatusManageOpenGetAdditionalCharge.MODE_REPLACE); event.setSumma(result); } } } }
И собственно результат
P.S. На основе данного скрипта так же был реализована акция "3+1". Т.е. при приходе платежа проверяется сумма платежа и если она больше или равна tariffPrice*3 - активируется тарифная опция как на скрине выше