Предоставление тестового периода пользования услугой
Материал из BiTel WiKi
Для версии 5.1.
Клиенту после подключения предоставляется тестовый период равный трём дням. В течении трёх дней клиент должен оплатить сумму месячной абонплат. В противном случае договор блокируется. При активации договора по достаточному платежу абонплата открывается от начала месяца либо даты первой установки статуса активен (что было позже). Для того, чтобы система работала, к договору должен быть подключен скрипт поведения Тестовый период.
Библиотека скриптов test_period.
// код экземпляра модуля и услуги абонплаты int NPAY_MID = 2; int ABON_SID = 21; // число дней тестового периода int DAYS_TEST_PERIOD = 3; // код скрипта "Тестовый период" int TEST_PERIOD_SCRIPT_ID = 8; // возвращает МАКСИМУМ(ДАТА_НАЧАЛА_МЕСЯЦА; ДАТА_ПЕРВОГО_СТАТУСА_АКТИВЕН) private Calendar getActiveStartDate( con, cid, now, useStartMonthIfLater ) { Calendar result = null; String query = "SELECT date1 FROM contract_status WHERE cid=? AND status=? ORDER BY date1 LIMIT 1"; PreparedStatement ps = con.prepareStatement( query ); ps.setInt( 1, cid ); ps.setInt( 2, KernelConst.CONTRACT_STATUS_ACTIVE ); ResultSet rs = ps.executeQuery(); if( rs.next() ) { result = TimeUtils.convertDateToCalendar( rs.getDate( 1 ) ); } if( result != null && useStartMonthIfLater ) { Calendar startMonth = TimeUtils.getStartMonth( now ); if( TimeUtils.dateBefore( result, startMonth ) ) { result = startMonth; } } return result; }
Глобальный скрипт Тестовый период - блокировка, запускается раз в сутки для блокировки договоров с истекшим тестовым периодом без абонплаты.
import java.sql.*; import bitel.billing.server.util.*; import bitel.billing.server.contract.bean.*; import bitel.billing.server.admin.bean.*; import bitel.billing.common.*; includeBGBS( "bgbs://ru.bitel.bgbilling.kernel.script.common.bean.ScriptLibrary/test_period" ); public void main( setup, con, conSlave ) { Calendar now = new GregorianCalendar(); // активные договора без абонплаты String query = "SELECT contract.id, contract.title, service_object.id FROM contract " + "INNER JOIN contract_script ON contract.id=contract_script.cid AND contract_script.script_id=? " + "LEFT JOIN npay_service_object_" + NPAY_MID + " AS service_object ON contract.id=service_object.cid AND service_object.sid=? " + "WHERE contract.status=? " + "HAVING service_object.id IS NULL"; PreparedStatement ps = con.prepareStatement( query ); ps.setInt( 1, TEST_PERIOD_SCRIPT_ID ); ps.setInt( 2, ABON_SID ); ps.setInt( 3, KernelConst.CONTRACT_STATUS_ACTIVE ); ResultSet rs = ps.executeQuery(); while( rs.next() ) { int cid = rs.getInt( 1 ); String title = rs.getString( 2 ); Calendar firstActiveDate = getActiveStartDate( con, cid, now, false ); print( "Contract id: " + cid + "; title: " + title + "; firstActiveDate: " + TimeUtils.formatDate( firstActiveDate ) ); if( firstActiveDate != null && TimeUtils.daysDelta( firstActiveDate, now ) > DAYS_TEST_PERIOD ) { print( "Locking: " + title ); // установка статуса "Закрыт" ContractStatus status = new ContractStatus(); status.setContractId( cid ); status.setStatus( KernelConst.CONTRACT_STATUS_CLOSED ); status.setDateFrom( TimeUtils.convertCalendarToDate( now ) ); status.setComment( "Не оплатил в тестовый период" ); ContractStatusManager statusManager = new ContractStatusManager( con ); statusManager.changeStatus( status.clone(), User.USER_SERVER ); } } }
Функция Проверка возможности и открытие абонплаты скрипта поведения Тестовый период, обрабатывает события Изменение тарифа договора; Приход платежа.
import bitel.billing.common.*; import bitel.billing.server.util.*; import bitel.billing.server.task.bean.*; import bitel.billing.server.admin.bean.*; import bitel.billing.server.contract.bean.*; import bitel.billing.server.npay.*; import bitel.billing.server.npay.bean.*; import bitel.billing.common.KernelConst; import ru.bitel.common.*; import ru.bitel.bgbilling.modules.npay.server.*; import java.util.*; import java.sql.*; import java.math.*; includeBGBS( "bgbs://ru.bitel.bgbilling.kernel.script.common.bean.ScriptLibrary/test_period" ); public void onEvent( event, setup, con, conSlave ) { int cid = event.getContractId(); Contract contract = new ContractManager( con ).getContractByID( cid ); Calendar now = new GregorianCalendar(); Calendar startMonth = TimeUtils.getStartMonth( now ); Calendar endMonth = TimeUtils.getEndMonth( now ); ServiceObjectManager som = new ServiceObjectManager( con, NPAY_MID ); BalanceUtils bu = new BalanceUtils( con ); // проверка наличия абонплаты List serviceObjectList = som.getServiceObjectList( cid, null ); for( ServiceObject s : serviceObjectList ) { if( s.getServiceId() == ABON_SID ) { print( "Abon already exists" ); return; } } // определение даты начала Calendar activeStart = getActiveStartDate( con, cid, now, true ); if( activeStart == null ) { print( "Can't define active state date" ); return; } print( "First active date: " + TimeUtils.formatDate( activeStart ) ); print( "Calс abon to date: " + TimeUtils.formatDate( endMonth ) ); ServiceObject serviceObject = new ServiceObject(); serviceObject.setContractId( cid ); serviceObject.setServiceId( ABON_SID ); serviceObject.setDate1( TimeUtils.convertCalendarToDate( startMonth ) ); serviceObjectList.clear(); serviceObjectList.add( serviceObject ); BigDecimal planAccount = BigDecimal.ZERO; // предначисление до конца месяца Calculator calculator = new Calculator(); calculator.setExecutingTime( endMonth ); calculator.setPreCalc(); calculator.setActiveFromDate( startMonth ); calculator.setServiceObjectList( serviceObjectList ); calculator.initTask( setup, 0, "mid=" + NPAY_MID ); calculator.setCids( String.valueOf( cid ) ); calculator.startTask(); print( "Precalc for time: " + TimeUtils.formatDate( endMonth ) ); if( calculator.isCalcErrors() ) { print( "Precalc to end month errors!" ); return; } Map planAccountMap = calculator.getCostCache().getContractAccounts(); if( planAccountMap.get( cid ) == null ) { print( "Can't calculate plan account" ); return; } planAccount = planAccountMap.get( cid ); print( "planAccount=" + planAccount ); BigDecimal balance = bu.getBalance( TimeUtils.convertCalendarToDate( now ), cid ); print( "Balance: " + balance ); if( balance.compareTo( planAccount ) < 0 ) { print( "No enouth money for abon open!" ); return; } print( "Balance ok, opening abon." ); // открытие абонплаты serviceObject.setDate1( TimeUtils.convertCalendarToDate( activeStart ) ); som.updateServiceObject( serviceObject ); // установка статуса "Активен" - в случае его разблокировки по оплате if( contract.getStatus() == KernelConst.CONTRACT_STATUS_CLOSED ) { ContractStatus status = new ContractStatus(); status.setContractId( cid ); status.setStatus( KernelConst.CONTRACT_STATUS_ACTIVE ); status.setDateFrom( TimeUtils.convertCalendarToDate( now ) ); status.setComment( "Активация по оплате в тестовый период" ); ContractStatusManager statusManager = new ContractStatusManager( con ); statusManager.changeStatus( status.clone(), User.USER_SERVER ); } // запуск реального начисления new RunTaskDataManager( con ).addTask( new Recalculator( NPAY_MID, now, null, 0, String.valueOf( cid ), "Автоматическое открытие абонплаты" ) ); // разблокировка возможности понижения лимита new LimitManager( con ).setLimitManageMode( User.USER_SERVER, cid, 0 ); }
Функция Блокирование возможности понижения лимита скрипта поведения Тестовый период, обрабатывает события Договор создан.
import bitel.billing.server.util.*; import bitel.billing.server.admin.bean.*; import bitel.billing.server.contract.bean.*; public void onEvent( event, setup, con, conSlave ) { int cid = event.getContractId(); new LimitManager( con ).setLimitManageMode( User.USER_SERVER, cid, 1 ); }