Снятие абонентской платы в дебитовых договорах

Материал из BiTel WiKi

(Различия между версиями)
Перейти к: навигация, поиск
Строка 4: Строка 4:
В начале дня, до начисление абонентской платы, генерируется событие таймера с flag=1.   
В начале дня, до начисление абонентской платы, генерируется событие таймера с flag=1.   
По этому событию запускается скрипт проверки баланса. Если текущий баланс договора не позволяет списать абонентскую плату,  
По этому событию запускается скрипт проверки баланса. Если текущий баланс договора не позволяет списать абонентскую плату,  
-
то договор приостанавливается с комментарием "Недостаточно средств" добавляется в группу "Недостаточно средств".
+
то договор приостанавливается с комментарием "Недостаточно средств" и добавляется в группу "Недостаточно средств".
Далее для договоров, входящих к группу "Недостаточно средств", при приходе платежа делается проверка. Если текущий баланс позволяет списать абонентскую плату, то статус договора меняется на "активен" с комментарием "Автоматически после оплаты" и договор исключается из группы "Недостаточно средств". Так же для договоров, входящих в группу "Недостаточно средств", есть возможность выполнить доп. действие "Принудительно разблокировать договор". Если его выполнить, то статус договора будет изменен на "активен" с комментарием "Принудительно из доп. действия" и договор будет исключен из группы "Недостаточно средств".
Далее для договоров, входящих к группу "Недостаточно средств", при приходе платежа делается проверка. Если текущий баланс позволяет списать абонентскую плату, то статус договора меняется на "активен" с комментарием "Автоматически после оплаты" и договор исключается из группы "Недостаточно средств". Так же для договоров, входящих в группу "Недостаточно средств", есть возможность выполнить доп. действие "Принудительно разблокировать договор". Если его выполнить, то статус договора будет изменен на "активен" с комментарием "Принудительно из доп. действия" и договор будет исключен из группы "Недостаточно средств".

Версия 10:14, 17 апреля 2009

Приведу пример набора скриптов, для снятия абонентской платы в договорах, работающий по предоплате.

Описание: В начале дня, до начисление абонентской платы, генерируется событие таймера с flag=1. По этому событию запускается скрипт проверки баланса. Если текущий баланс договора не позволяет списать абонентскую плату, то договор приостанавливается с комментарием "Недостаточно средств" и добавляется в группу "Недостаточно средств". Далее для договоров, входящих к группу "Недостаточно средств", при приходе платежа делается проверка. Если текущий баланс позволяет списать абонентскую плату, то статус договора меняется на "активен" с комментарием "Автоматически после оплаты" и договор исключается из группы "Недостаточно средств". Так же для договоров, входящих в группу "Недостаточно средств", есть возможность выполнить доп. действие "Принудительно разблокировать договор". Если его выполнить, то статус договора будет изменен на "активен" с комментарием "Принудительно из доп. действия" и договор будет исключен из группы "Недостаточно средств".

Событие "Таймер"

import java.sql.*;
import java.util.*;
 
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.tariff.*;
import bitel.billing.server.util.*;
import bitel.billing.common.KernelConst; 
 
// код услуги
sid = 23;
// код экземпляра модуля
mid = 7;
//Группа "Недостаточно средств"
GROUP_ERROR_BALANCE = 19;
 
if( event.getFlag() != 1 ) {
    return;
};
 
cid = event.getContractID();
DateNow = new GregorianCalendar();
contract = new ContractManager(con).getContractByID(cid);
if (contract == null){
	return;
};
BalanceMode = contract.getBalanceMode();
if (BalanceMode == 0){
	//Пропускаем тех кто работает по факту
	return;
};
contract_status_manager  = new ContractStatusManager(con);
status = contract_status_manager.getStatus(cid, DateNow);
contract_status = status.getStatus();
 
if (contract_status == null)
{
	contract_status = KernelConst.CONTRACT_STATUS_ACTIVE;
};
if (contract_status != KernelConst.CONTRACT_STATUS_ACTIVE) 
{
	//Пропускаем не активные договора
	return;
};
 
date_str=TimeUtils.format(DateNow, "yyyy-MM-dd"); 
 
//Проверяем привязана ли услуга "абонплата"
abn_count = "0";
query_check_abn = 
" SELECT npay_service_object_"+mid+".col"+
" FROM contract_service"+
"   LEFT JOIN npay_service_object_"+mid+
"   ON (contract_service.id=npay_service_object_"+mid+".csid)"+
" WHERE (contract_service.date1 is NULL OR contract_service.date1<='"+date_str+"') AND"+
" (contract_service.date2 is NULL OR contract_service.date2>='"+date_str+"') AND"+
" contract_service.sid='"+sid+"' AND contract_service.cid='"+cid+"'";
re_check_abn = con.prepareStatement(query_check_abn);
ResultSet re_check_abn = re_check_abn.executeQuery();
while (re_check_abn.next())
{
	if (re_check_abn.getString(1) == null)
	{
		abn_count = "1";
	}
	else
	{
		abn_count = re_check_abn.getString(1);
	};
};
abn_count = Double.parseDouble(abn_count);
if (abn_count == 0)
{
	//Услуга не найдена.
	return;
};
 
day_str=TimeUtils.format(DateNow, "dd"); 
day = Double.parseDouble(day_str);
 
cost = null;
cost_type = null;
calc_mode = null;
calc_type = null;
// поиск параметров абонплаты
tts = new ContractManager( con ).getRealtimeTariffTreeSet( cid, DateNow, "npay", mid, true );
for( TariffModuleTree tree : tts.getTreeList( DateNow ) )
{
	req_cost = new TariffRequest();
	req_cost.setRequestParam( "action", "calculate" );
	req_cost.setRequestParam( "sid", sid );
	req_cost.setRequestParam( "month_days", 1 );
	req_cost.setRequestParam( "period_days", 1 );
	req_cost.setRequestParam( "time",  DateNow);
	tree.processRequest( req_cost );
	cost = (Double)req_cost.getResponseParam( "cost" );
	cost_type = req_cost.getResponseParam( "cost_type" );
 
	req_calc_mode = new TariffRequest();
	req_calc_mode.setRequestParam( "action", "reset" );
	req_calc_mode.setRequestParam( "sid", sid );
	req_calc_mode.setRequestParam( "time",  DateNow);
	tree.processRequest( req_calc_mode );
	calc_mode = (String)req_calc_mode.getResponseParam( "calc_mode" );
	calc_type = req_calc_mode.getResponseParam( "calc_type" );
};
 
if (cost == null || calc_mode == null)
{
	error ("Параметры абонплаты не найдены");
	return;
};
if (calc_mode.indexOf("month") != -1 && day != 1)
{
	//абонплату за месяц снимаем проверяем только 1-ого числа
	return;
};
if (calc_mode.indexOf("day") != -1 && (cost_type != 0 || calc_type != 1))
{
	error ("Неверные параметры тарифа");
	return;
};
if (cost == 0)
{
	return;
};
 
cost = cost*abn_count;
print ("cid="+cid);
balance = new BalanceUtils(con);
contract_balance = balance.getBalance (new Date(), cid);
contract_limit = contract.getBalanceLimit();
print ("contract_balance="+contract_balance);  
print ("contract_limit="+contract_limit);  
print ("contract_abn="+cost);
contract_balance_new = contract_balance - cost;
print ("contract_balance_new="+contract_balance_new);
if (contract_balance_new >= contract_limit)
{
	print ("Balance OK");
}
else
{
	print ("Balance error");
 
	contract_groups = contract.getGroups();
	contract_groups = contract_groups | 1L<<GROUP_ERROR_BALANCE;
 
	query = "UPDATE contract SET gr=? WHERE id=?";
	psUpdate = con.prepareStatement( query );
	psUpdate.setLong( 1, contract_groups );
	psUpdate.setInt( 2, cid );
	psUpdate.executeUpdate();
 
	ContractStatus status = new ContractStatus();
	status.setContractId( cid );
	status.setDate1( DateNow	 );
	status.setDate2( null );
	status.setStatus( KernelConst.CONTRACT_STATUS_SUSPENDED );
	status.setComment( "Недостаточно средств" );
	status.setUserId( 0 );
	contract_status_manager.changeStatus( status ); 	
};

Событие "Приход тлатежа"

import java.sql.*;
import java.util.*;
 
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.tariff.*;
import bitel.billing.server.util.*;
import bitel.billing.common.KernelConst; 
 
// код услуги
sid = 23;
// код экземпляра модуля
mid = 7;
//Группа "Недостаточно средств"
GROUP_ERROR_BALANCE = 19;
 
DateNow = new GregorianCalendar();
cid = event.getContractID();
contract = new ContractManager(con).getContractByID(cid);
contract_groups = contract.getGroups();
if ((contract_groups & (1L<<GROUP_ERROR_BALANCE)) == 0)
{
	return;
};
 
BalanceMode = contract.getBalanceMode();
if (BalanceMode == 0){
	//Пропускаем тех кто работает по факту
	return;
};
 
contract_status_manager  = new ContractStatusManager(con);
status = contract_status_manager.getStatus(cid, DateNow);
contract_status = status.getStatus();
 
if (contract_status == null)
{
	contract_status = KernelConst.CONTRACT_STATUS_ACTIVE;
};
 
date_str=TimeUtils.format(DateNow, "yyyy-MM-dd"); 
 
//Проверяем привязана ли услуга "абонплата"
abn_count = "0";
query_check_abn = 
" SELECT npay_service_object_"+mid+".col"+
" FROM contract_service"+
"   LEFT JOIN npay_service_object_"+mid+
"   ON (contract_service.id=npay_service_object_"+mid+".csid)"+
" WHERE (contract_service.date1 is NULL OR contract_service.date1<='"+date_str+"') AND"+
" (contract_service.date2 is NULL OR contract_service.date2>='"+date_str+"') AND"+
" contract_service.sid='"+sid+"' AND contract_service.cid='"+cid+"'";
re_check_abn = con.prepareStatement(query_check_abn);
ResultSet re_check_abn = re_check_abn.executeQuery();
while (re_check_abn.next())
{
	if (re_check_abn.getString(1) == null)
	{
		abn_count = "1";
	}
	else
	{
		abn_count = re_check_abn.getString(1);
	};
};
abn_count = Double.parseDouble(abn_count);
if (abn_count == 0)
{
	//Услуга не найдена.
	return;
};
 
cost = null;
cost_type = null;
calc_mode = null;
calc_type = null;
// поиск параметров абонплаты
tts = new ContractManager( con ).getRealtimeTariffTreeSet( cid, DateNow, "npay", mid, true );
for( TariffModuleTree tree : tts.getTreeList( DateNow ) )
{
	req_cost = new TariffRequest();
	req_cost.setRequestParam( "action", "calculate" );
	req_cost.setRequestParam( "sid", sid );
	req_cost.setRequestParam( "month_days", 1 );
	req_cost.setRequestParam( "period_days", 1 );
	req_cost.setRequestParam( "time",  DateNow);
	tree.processRequest( req_cost );
	cost = (Double)req_cost.getResponseParam( "cost" );
	cost_type = req_cost.getResponseParam( "cost_type" );
 
	req_calc_mode = new TariffRequest();
	req_calc_mode.setRequestParam( "action", "reset" );
	req_calc_mode.setRequestParam( "sid", sid );
	req_calc_mode.setRequestParam( "time",  DateNow);
	tree.processRequest( req_calc_mode );
	calc_mode = (String)req_calc_mode.getResponseParam( "calc_mode" );
	calc_type = req_calc_mode.getResponseParam( "calc_type" );
};
 
if (cost == null || calc_mode == null)
{
	error ("Параметры абонплаты не найдены");
	return;
};
if (calc_mode.indexOf("day") != -1 && (cost_type != 0 || calc_type != 1))
{
	error ("Неверные параметры тарифа");
	return;
};
if (calc_mode.indexOf("day") != -1)
{
	cost = cost*abn_count*30;
};
if (calc_mode.indexOf("month") != -1)
{
	cost = cost*abn_count;
};
print ("cid="+cid);
balance = new BalanceUtils(con);
contract_balance = balance.getBalance (new Date(), cid);
contract_limit = contract.getBalanceLimit();
print ("contract_balance="+contract_balance);  
print ("contract_limit="+contract_limit);  
print ("contract_abn="+cost);
contract_balance_new = contract_balance - cost;
print ("contract_balance_new="+contract_balance_new);
 
if (contract_balance_new >= contract_limit)
{
	print ("Balance OK");
 
	contract_groups = contract_groups & ~(1L<<GROUP_ERROR_BALANCE);
 
	query = "UPDATE contract SET gr=? WHERE id=?";
	psUpdate = con.prepareStatement( query );
	psUpdate.setLong( 1, contract_groups );
	psUpdate.setInt( 2, cid );
	psUpdate.executeUpdate();
 
	if (contract_status != KernelConst.CONTRACT_STATUS_ACTIVE) 
	{
		ContractStatus status = new ContractStatus();
		status.setContractId( cid );
		status.setDate1( DateNow	 );
		status.setDate2( null );
		status.setStatus( KernelConst.CONTRACT_STATUS_ACTIVE );
		status.setComment( "Автоматически после оплаты" );
		status.setUserId( 0 );
		contract_status_manager.changeStatus( status ); 	
	};
}
else
{
	print ("Balance error");
};

Событие "Обработка доп. действия для договора"

import java.sql.*;
import java.util.*;
 
import bitel.billing.server.contract.bean.*;
import bitel.billing.common.KernelConst; 
 
if (event.getActionId() != 21) 
{ 
	print("skipped");
	return; 
}
 
//Группа "Недостаточно средств"
GROUP_ERROR_BALANCE = 19;
 
DateNow = new GregorianCalendar();
cid = event.getContractID();
contract = new ContractManager(con).getContractByID(cid);
contract_groups = contract.getGroups();
 
contract_status_manager  = new ContractStatusManager(con);
status = contract_status_manager.getStatus(cid, DateNow);
contract_status = status.getStatus();
 
if (contract_status == null)
{
	contract_status = KernelConst.CONTRACT_STATUS_ACTIVE;
};
 
contract_groups = contract_groups & ~(1L<<GROUP_ERROR_BALANCE);
 
query = "UPDATE contract SET gr=? WHERE id=?";
psUpdate = con.prepareStatement( query );
psUpdate.setLong( 1, contract_groups );
psUpdate.setInt( 2, cid );
psUpdate.executeUpdate();
 
if (contract_status != KernelConst.CONTRACT_STATUS_ACTIVE) 
{
	ContractStatus status = new ContractStatus();
	status.setContractId( cid );
	status.setDate1( DateNow	 );
	status.setDate2( null );
	status.setStatus( KernelConst.CONTRACT_STATUS_ACTIVE );
	status.setComment( "Принудительно из доп. действия" );
	status.setUserId( 0 );
	contract_status_manager.changeStatus( status ); 	
};

Событие "Получить список доп. действия для договора"

import bitel.billing.server.contract.bean.*;
 
//Группа "Недостаточно средств"
GROUP_ERROR_BALANCE = 19;
 
cid = event.getContractID(); 
contract = new ContractManager(con).getContractByID(cid);
contract_groups = contract.getGroups();
 
contract_is_group_error_balance = (contract_groups & (1L<<GROUP_ERROR_BALANCE)) > 0;
 
if (contract_is_group_error_balance)
{
	event.addAction( 21, "Принудительно разблокировать договор" );
};
Личные инструменты