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

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

(Различия между версиями)
Перейти к: навигация, поиск
Строка 286: Строка 286:
if (calc_mode.indexOf("day") != -1)
if (calc_mode.indexOf("day") != -1)
{
{
 +
//При снятии абонплаты за день клиент должен оплатить как минимум за 30 дней
cost = cost*abn_count*30;
cost = cost*abn_count*30;
};
};

Версия 10:25, 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)
{
	//При снятии абонплаты за день клиент должен оплатить как минимум за 30 дней
	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, "Принудительно разблокировать договор" );
};
Личные инструменты