Открытие абонплаты по первой установке соединения
Материал из BiTel WiKi
Admin (Обсуждение | вклад) (Новая страница: «Версия биллинга - 5.1. Скрипт открывает абонентскую плату на договоре по первой авторизаци…») |
Admin (Обсуждение | вклад) |
||
(2 промежуточные версии не показаны) | |||
Строка 44: | Строка 44: | ||
new ServiceObjectManager( con, NPAY_MID ).updateServiceObject( serviceObject ); | new ServiceObjectManager( con, NPAY_MID ).updateServiceObject( serviceObject ); | ||
new RunTaskDataManager( con ).addTask( new Recalculator( NPAY_MID, new GregorianCalendar(), null, 0, String.valueOf( contractId ), "Автоматическое открытие абонплаты" ) ); | new RunTaskDataManager( con ).addTask( new Recalculator( NPAY_MID, new GregorianCalendar(), null, 0, String.valueOf( contractId ), "Автоматическое открытие абонплаты" ) ); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Усложнённая версия скрипта. В дополнение снимает группу и устанавливает начало тарифного плана на дату первого входа. Это может быть необходимо при использовании в тарифах узла '''Диапазон наработки''' в режиме пропорциональном тарифу. | ||
+ | Обратите внимание, что изменяется период также и закэшированного в памяти тарифа, который будет использоваться при тарификации первой сессии. | ||
+ | |||
+ | <source lang="java"> | ||
+ | import bitel.billing.server.util.*; | ||
+ | import bitel.billing.server.task.bean.*; | ||
+ | import java.sql.*; | ||
+ | import ru.bitel.bgbilling.kernel.network.radius.*; | ||
+ | import bitel.billing.server.npay.bean.*; | ||
+ | import bitel.billing.server.npay.*; | ||
+ | import java.util.*; | ||
+ | import bitel.billing.server.contract.bean.*; | ||
+ | |||
+ | int NPAY_MID = 1; | ||
+ | int SERVICE = 1; | ||
+ | int GROUP_ID = 18; | ||
+ | |||
+ | public void onEvent( event, setup, con, conSlave ) | ||
+ | { | ||
+ | int contractId = event.getContractId(); | ||
+ | RadiusPacket packet = event.getResponse(); | ||
+ | |||
+ | if( packet.getCode() == RadiusPacket.ACCESS_ACCEPT ) | ||
+ | { | ||
+ | print( "It's accept packet" ); | ||
+ | |||
+ | String tableName = "npay_service_object_" + NPAY_MID; | ||
+ | String query = "SELECT COUNT(*) FROM " + tableName + " WHERE cid=? AND sid=?"; | ||
+ | |||
+ | PreparedStatement ps = con.prepareStatement( query ); | ||
+ | ps.setInt( 1, contractId ); | ||
+ | ps.setInt( 2, SERVICE ); | ||
+ | |||
+ | ResultSet rs = ps.executeQuery(); | ||
+ | if( !rs.next() || rs.getInt( 1 ) == 0 ) | ||
+ | { | ||
+ | print( "Adding service" ); | ||
+ | |||
+ | ServiceObject serviceObject = new ServiceObject(); | ||
+ | serviceObject.setContractId( contractId ); | ||
+ | serviceObject.setServiceId( SERVICE ); | ||
+ | serviceObject.setDate1( new java.util.Date() ); | ||
+ | |||
+ | new ServiceObjectManager( con, NPAY_MID ).updateServiceObject( serviceObject ); | ||
+ | new RunTaskDataManager( con ).addTask( new Recalculator( NPAY_MID, new GregorianCalendar(), null, 0, String.valueOf( contractId ), "Автоматическое открытие абонплаты" ) ); | ||
+ | |||
+ | ContractTariffManager ctm = new ContractTariffManager( con ); | ||
+ | |||
+ | // изменение периода тарифного плана | ||
+ | List tariffList = ctm.getContractTariffList( contractId, (java.util.Date)null ); | ||
+ | for( ContractTariff tariff : tariffList ) | ||
+ | { | ||
+ | tariff.setDate1( new GregorianCalendar() ); | ||
+ | ctm.updateContractTariff( tariff ); | ||
+ | } | ||
+ | |||
+ | // удаление группы | ||
+ | query = "UPDATE contract SET gr = gr&(~(1<<?)) WHERE id=?"; | ||
+ | ps = con.prepareStatement( query ); | ||
+ | ps.setInt( 1, GROUP_ID ); | ||
+ | ps.setInt( 2, contractId ); | ||
+ | ps.executeUpdate(); | ||
+ | |||
+ | java.util.Date now = new java.util.Date(); | ||
+ | |||
+ | // изменение в кэше | ||
+ | TariffTreeSet tts = event.getContract().getTts(); | ||
+ | for( TariffSetEntry tse : tts.getEntries() ) | ||
+ | { | ||
+ | tse.setDateFrom( now ); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Усложнённая версия скрипта. При отсутствии абонплаты в договоре оценивает, достаточно ли в данный момент средств для списания абонплаты до конца текущего месяца без перевода договор в минус. | ||
+ | Если средств недостаточно - Accept пакет подменяется на Reject. Если достаточно - открывается абонплата от текущего момента, период тарифа в базе и кэше радиуса меняется (для корректной работы узлов типа "Диапазон наработки"). | ||
+ | |||
+ | <source lang="java"> | ||
+ | import ru.bitel.common.*; | ||
+ | import bitel.billing.server.task.bean.*; | ||
+ | import java.sql.*; | ||
+ | import java.math.*; | ||
+ | import ru.bitel.bgbilling.kernel.network.radius.*; | ||
+ | import bitel.billing.server.npay.bean.*; | ||
+ | import bitel.billing.server.npay.*; | ||
+ | import java.util.*; | ||
+ | import bitel.billing.server.contract.bean.*; | ||
+ | import bitel.billing.server.tariff.*; | ||
+ | import bitel.billing.server.tariff.TariffTreeSet.TariffSetEntry; | ||
+ | import ru.bitel.bgbilling.modules.npay.server.*; | ||
+ | |||
+ | int NPAY_MID = 1; | ||
+ | int SERVICE = 1; | ||
+ | |||
+ | int GROUP_ID = 18; | ||
+ | |||
+ | public void onEvent( event, setup, con, conSlave ) | ||
+ | { | ||
+ | int contractId = event.getContractId(); | ||
+ | RadiusPacket packet = event.getResponse(); | ||
+ | |||
+ | if( packet.getCode() == RadiusPacket.ACCESS_ACCEPT ) | ||
+ | { | ||
+ | print( "It's accept packet" ); | ||
+ | |||
+ | ContractTariffManager ctm = new ContractTariffManager( con ); | ||
+ | ContractParameterManager cpm = new ContractParameterManager( con ); | ||
+ | ServiceObjectManager som = new ServiceObjectManager( con, NPAY_MID ); | ||
+ | BalanceUtils bu = new BalanceUtils( con ); | ||
+ | |||
+ | Contract contract = event.getContract(); | ||
+ | java.util.Date curdate = new java.util.Date(); | ||
+ | Calendar now = new GregorianCalendar(); | ||
+ | |||
+ | String tableName = "npay_service_object_" + NPAY_MID; | ||
+ | String query = "SELECT COUNT(*) FROM " + tableName + " WHERE cid=? AND sid=?"; | ||
+ | |||
+ | PreparedStatement ps = con.prepareStatement( query ); | ||
+ | ps.setInt( 1, contractId ); | ||
+ | ps.setInt( 2, SERVICE ); | ||
+ | |||
+ | ResultSet rs = ps.executeQuery(); | ||
+ | if( !rs.next() || rs.getInt( 1 ) == 0 ) | ||
+ | { | ||
+ | print( "Contract hasn't abon." ); | ||
+ | |||
+ | ServiceObject serviceObject = new ServiceObject(); | ||
+ | serviceObject.setContractId( contractId ); | ||
+ | serviceObject.setServiceId( SERVICE ); | ||
+ | serviceObject.setDate1( curdate ); | ||
+ | |||
+ | List serviceObjectList = new ArrayList(); | ||
+ | serviceObjectList.add( serviceObject ); | ||
+ | |||
+ | packet.setCode( RadiusPacket.ACCESS_REJECT ); | ||
+ | |||
+ | Calculator calculator = new Calculator(); | ||
+ | calculator.setExecutingTime( now ); | ||
+ | calculator.setPreCalc(); | ||
+ | calculator.setServiceObjectList( serviceObjectList ); | ||
+ | calculator.initTask( setup, 0, "mid=" + NPAY_MID ); | ||
+ | calculator.setCids( String.valueOf( contractId ) ); | ||
+ | calculator.startTask(); | ||
+ | |||
+ | if( !calculator.isCalcErrors() ) | ||
+ | { | ||
+ | Map planAccountMap = calculator.getCostCache().getContractAccounts(); | ||
+ | BigDecimal planAccount = Utils.maskNull( (BigDecimal)planAccountMap.get( contractId ) ); | ||
+ | |||
+ | print( "Plan account: " + planAccount ); | ||
+ | |||
+ | BigDecimal balance = bu.getBalance( curdate, contractId ); | ||
+ | if( balance.compareTo( planAccount ) < 0 ) | ||
+ | { | ||
+ | print( "No enouth money for abon open!" ); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | // добавление абонплаты и запуск её начисления | ||
+ | serviceObject = new ServiceObject(); | ||
+ | serviceObject.setContractId( contractId ); | ||
+ | serviceObject.setServiceId( SERVICE ); | ||
+ | serviceObject.setDate1( curdate ); | ||
+ | |||
+ | new ServiceObjectManager( con, NPAY_MID ).updateServiceObject( serviceObject ); | ||
+ | new RunTaskDataManager( con ).addTask( new Recalculator( NPAY_MID, new GregorianCalendar(), null, 0, String.valueOf( contractId ), "Автоматическое открытие абонплаты" ) ); | ||
+ | |||
+ | // изменение периода тарифного плана | ||
+ | List tariffList = ctm.getContractTariffList( contractId, curdate ); | ||
+ | for( ContractTariff tariff : tariffList ) | ||
+ | { | ||
+ | tariff.setDate1( now ); | ||
+ | ctm.updateContractTariff( tariff ); | ||
+ | } | ||
+ | |||
+ | // удаление группы | ||
+ | cpm.unsetGroup( contractId, GROUP_ID ); | ||
+ | |||
+ | // изменение в кэше | ||
+ | TariffTreeSet tts = event.getContract().getTts(); | ||
+ | for( TariffSetEntry tse : tts.getEntries() ) | ||
+ | { | ||
+ | tse.setDateFrom( curdate ); | ||
+ | } | ||
+ | |||
+ | packet.setCode( RadiusPacket.ACCESS_ACCEPT ); | ||
+ | } | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | print( "Precalc errors!" ); | ||
+ | } | ||
} | } | ||
} | } | ||
} | } | ||
</source> | </source> |
Текущая версия на 06:11, 20 июля 2010
Версия биллинга - 5.1.
Скрипт открывает абонентскую плату на договоре по первой авторизации, если её не было и передаёт задание планировщику произвести начисление абонплат. Есть небольшой "костыль" - необходимо в BGRadiusDialup/lib либо скопировать либо сделать символическую ссылку на библиотеку BGBillingServer/lib/npay.jar. Т.к. скрипту нужны классы этой библиотеки.
Скрипт - обрабатывает событие RADIUS-аунтификация модуля DialUp.
import bitel.billing.server.util.*; import bitel.billing.server.task.bean.*; import java.sql.*; import ru.bitel.bgbilling.kernel.network.radius.*; import bitel.billing.server.npay.bean.*; import bitel.billing.server.npay.*; import java.util.*; int NPAY_MID = 1; int SERVICE = 1; public void onEvent( event, setup, con, conSlave ) { int contractId = event.getContractId(); RadiusPacket packet = event.getResponse(); if( packet.getCode() == RadiusPacket.ACCESS_ACCEPT ) { print( "It's accept packet" ); String tableName = "npay_service_object_" + NPAY_MID; String query = "SELECT COUNT(*) FROM " + tableName + " WHERE cid=? AND sid=?"; PreparedStatement ps = con.prepareStatement( query ); ps.setInt( 1, contractId ); ps.setInt( 2, SERVICE ); ResultSet rs = ps.executeQuery(); if( !rs.next() || rs.getInt( 1 ) == 0 ) { print( "Adding service" ); ServiceObject serviceObject = new ServiceObject(); serviceObject.setContractId( contractId ); serviceObject.setServiceId( SERVICE ); serviceObject.setDate1( new java.util.Date() ); new ServiceObjectManager( con, NPAY_MID ).updateServiceObject( serviceObject ); new RunTaskDataManager( con ).addTask( new Recalculator( NPAY_MID, new GregorianCalendar(), null, 0, String.valueOf( contractId ), "Автоматическое открытие абонплаты" ) ); } } }
Усложнённая версия скрипта. В дополнение снимает группу и устанавливает начало тарифного плана на дату первого входа. Это может быть необходимо при использовании в тарифах узла Диапазон наработки в режиме пропорциональном тарифу. Обратите внимание, что изменяется период также и закэшированного в памяти тарифа, который будет использоваться при тарификации первой сессии.
import bitel.billing.server.util.*; import bitel.billing.server.task.bean.*; import java.sql.*; import ru.bitel.bgbilling.kernel.network.radius.*; import bitel.billing.server.npay.bean.*; import bitel.billing.server.npay.*; import java.util.*; import bitel.billing.server.contract.bean.*; int NPAY_MID = 1; int SERVICE = 1; int GROUP_ID = 18; public void onEvent( event, setup, con, conSlave ) { int contractId = event.getContractId(); RadiusPacket packet = event.getResponse(); if( packet.getCode() == RadiusPacket.ACCESS_ACCEPT ) { print( "It's accept packet" ); String tableName = "npay_service_object_" + NPAY_MID; String query = "SELECT COUNT(*) FROM " + tableName + " WHERE cid=? AND sid=?"; PreparedStatement ps = con.prepareStatement( query ); ps.setInt( 1, contractId ); ps.setInt( 2, SERVICE ); ResultSet rs = ps.executeQuery(); if( !rs.next() || rs.getInt( 1 ) == 0 ) { print( "Adding service" ); ServiceObject serviceObject = new ServiceObject(); serviceObject.setContractId( contractId ); serviceObject.setServiceId( SERVICE ); serviceObject.setDate1( new java.util.Date() ); new ServiceObjectManager( con, NPAY_MID ).updateServiceObject( serviceObject ); new RunTaskDataManager( con ).addTask( new Recalculator( NPAY_MID, new GregorianCalendar(), null, 0, String.valueOf( contractId ), "Автоматическое открытие абонплаты" ) ); ContractTariffManager ctm = new ContractTariffManager( con ); // изменение периода тарифного плана List tariffList = ctm.getContractTariffList( contractId, (java.util.Date)null ); for( ContractTariff tariff : tariffList ) { tariff.setDate1( new GregorianCalendar() ); ctm.updateContractTariff( tariff ); } // удаление группы query = "UPDATE contract SET gr = gr&(~(1<<?)) WHERE id=?"; ps = con.prepareStatement( query ); ps.setInt( 1, GROUP_ID ); ps.setInt( 2, contractId ); ps.executeUpdate(); java.util.Date now = new java.util.Date(); // изменение в кэше TariffTreeSet tts = event.getContract().getTts(); for( TariffSetEntry tse : tts.getEntries() ) { tse.setDateFrom( now ); } } } }
Усложнённая версия скрипта. При отсутствии абонплаты в договоре оценивает, достаточно ли в данный момент средств для списания абонплаты до конца текущего месяца без перевода договор в минус. Если средств недостаточно - Accept пакет подменяется на Reject. Если достаточно - открывается абонплата от текущего момента, период тарифа в базе и кэше радиуса меняется (для корректной работы узлов типа "Диапазон наработки").
import ru.bitel.common.*; import bitel.billing.server.task.bean.*; import java.sql.*; import java.math.*; import ru.bitel.bgbilling.kernel.network.radius.*; import bitel.billing.server.npay.bean.*; import bitel.billing.server.npay.*; import java.util.*; import bitel.billing.server.contract.bean.*; import bitel.billing.server.tariff.*; import bitel.billing.server.tariff.TariffTreeSet.TariffSetEntry; import ru.bitel.bgbilling.modules.npay.server.*; int NPAY_MID = 1; int SERVICE = 1; int GROUP_ID = 18; public void onEvent( event, setup, con, conSlave ) { int contractId = event.getContractId(); RadiusPacket packet = event.getResponse(); if( packet.getCode() == RadiusPacket.ACCESS_ACCEPT ) { print( "It's accept packet" ); ContractTariffManager ctm = new ContractTariffManager( con ); ContractParameterManager cpm = new ContractParameterManager( con ); ServiceObjectManager som = new ServiceObjectManager( con, NPAY_MID ); BalanceUtils bu = new BalanceUtils( con ); Contract contract = event.getContract(); java.util.Date curdate = new java.util.Date(); Calendar now = new GregorianCalendar(); String tableName = "npay_service_object_" + NPAY_MID; String query = "SELECT COUNT(*) FROM " + tableName + " WHERE cid=? AND sid=?"; PreparedStatement ps = con.prepareStatement( query ); ps.setInt( 1, contractId ); ps.setInt( 2, SERVICE ); ResultSet rs = ps.executeQuery(); if( !rs.next() || rs.getInt( 1 ) == 0 ) { print( "Contract hasn't abon." ); ServiceObject serviceObject = new ServiceObject(); serviceObject.setContractId( contractId ); serviceObject.setServiceId( SERVICE ); serviceObject.setDate1( curdate ); List serviceObjectList = new ArrayList(); serviceObjectList.add( serviceObject ); packet.setCode( RadiusPacket.ACCESS_REJECT ); Calculator calculator = new Calculator(); calculator.setExecutingTime( now ); calculator.setPreCalc(); calculator.setServiceObjectList( serviceObjectList ); calculator.initTask( setup, 0, "mid=" + NPAY_MID ); calculator.setCids( String.valueOf( contractId ) ); calculator.startTask(); if( !calculator.isCalcErrors() ) { Map planAccountMap = calculator.getCostCache().getContractAccounts(); BigDecimal planAccount = Utils.maskNull( (BigDecimal)planAccountMap.get( contractId ) ); print( "Plan account: " + planAccount ); BigDecimal balance = bu.getBalance( curdate, contractId ); if( balance.compareTo( planAccount ) < 0 ) { print( "No enouth money for abon open!" ); } else { // добавление абонплаты и запуск её начисления serviceObject = new ServiceObject(); serviceObject.setContractId( contractId ); serviceObject.setServiceId( SERVICE ); serviceObject.setDate1( curdate ); new ServiceObjectManager( con, NPAY_MID ).updateServiceObject( serviceObject ); new RunTaskDataManager( con ).addTask( new Recalculator( NPAY_MID, new GregorianCalendar(), null, 0, String.valueOf( contractId ), "Автоматическое открытие абонплаты" ) ); // изменение периода тарифного плана List tariffList = ctm.getContractTariffList( contractId, curdate ); for( ContractTariff tariff : tariffList ) { tariff.setDate1( now ); ctm.updateContractTariff( tariff ); } // удаление группы cpm.unsetGroup( contractId, GROUP_ID ); // изменение в кэше TariffTreeSet tts = event.getContract().getTts(); for( TariffSetEntry tse : tts.getEntries() ) { tse.setDateFrom( curdate ); } packet.setCode( RadiusPacket.ACCESS_ACCEPT ); } } else { print( "Precalc errors!" ); } } } }