Пример автоматизации подключения новых клиентов

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

Перейти к: навигация, поиск

Приведу пример автоматизации работ, связанных с подключением новых абонентов.

Общая схема работы.

Оператор заключает договора на интернет или телефонию.

При создании договора, стоимость подключения автоматически прописывается в параметре договора и в персональном тарифе. Стоимость подключения, указанная в параметре договора, используется при печати договора и при определении определении минимальной суммы оплаты, после которой начнется процедура подключения. Стоимость подключения, указанная в персональном тарифе, списывается со счета абонента после окончания процедуры подключения.

Для физических лиц, стоимость подключения берется из глобального тарифа для услуг RSCM с кодами 17("Подключение - Интернет") и 29 ("Подключение - Телефонии"). А для юридических лиц всегда 0 р. Оператор, при необходимости, может изменить стоимость подключения.

При создании статус договора переводится с состояние "Приостановлен".

После создания и заполнения данных договора оператор должен принять решение. Он должен добавить договора в очередь "Ожидание оплаты подключения" или в очередь "Ожидание подключения". Происходит это через доп. действия договора.

При попадании в очередь "Ожидание оплаты подключения" договор помещается в группу "Ожидание оплаты подключения" с кодом 17. Для договоров, входящих в группу "Ожидание оплаты подключения" при приходе платежа делается проверка. Если баланс договора (после занесения платежа) больше или равен стоимости подключения, прописанной в параметрах договора, то договора автоматически помещается в очередь "Ожидание подключения" и исключается из группы "Ожидание оплаты подключения". Если баланс договора меньше стоимости подключения, то в CRM создается задача, в которого говориться что оплата не достаточна и необходимо известить об этом абонента.



Событие "Договор создан" (Создание персонального тарифа на подключение)

import java.sql.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.tariff.*;
import bitel.billing.server.util.*;
import bitel.billing.server.script.bean.event.*;
import bitel.billing.server.service.bean.*;
import bitel.billing.server.contract.bean.*;
 
RSCM_ID = 9;				// код модуля RSCM
VPN_ID = 1;					// код модуля VPN
IPN_ID = 4;					// код модуля IPN
PHONE_ID = 5;				// код модуля Телефония
 
INTERNET_COST_NODE = 12293;// код узла, где хранится цена за подключение Интернета
PHONE_COST_NODE = 12295;	// код узла, где хранится цена за подключение Телефона
INTERNET_SERVICE_ID = 17;	// код услуги "Подключение - Интернет"
PHONE_SERVICE_ID = 29;		// код услуги "Подключение - Телефон"
PID_CONNECT_COST = 46;		// код параметра договора "Стоимость подключения"		
 
createPT(title, cost_node, service_id)
{
	print("Start creating tariff [" + title + "]");
 
	// создать ПТ
	pt = new PersonalTariff();
	pt.setContractId(cid);
	pt.setTitle(title);
	ptm.updatePersonalTariff(pt);
	// получить treeID
	tid = pt.getId();
	pt = ptm.getPersonalTariff(tid); 
	treeId = pt.getTreeId();
	print("Tariff created. TreeId: " + String.valueOf(treeId) );
 
	// сгенерировать lm
	lm = new Date().getTime();
	// добавить запись в module_tariff_tree и получить ее Id
	ps = con.prepareStatement( "INSERT INTO module_tariff_tree (mid, tree_id, lm) VALUES (?, ?, ?)" );
	ps.setInt( 1, RSCM_ID );
	ps.setInt( 2, treeId );
	ps.setLong( 3, lm );
	rs = ps.executeUpdate();
	print("INSERT INTO module_tariff_tree (mid, tree_id)" + 
          "VALUES (" + String.valueOf(RSCM_ID) +	"," + String.valueOf(treeId) +")");
	rs = con.prepareStatement( "select LAST_INSERT_ID()" ).executeQuery();
	rs.next();
	mttId = rs.getInt(1);
	print("mtree_id: " +  String.valueOf(mttId));
 
	// получить максимальное значение pos из mtree_node
	ps = con.prepareStatement( "SELECT MAX(pos) FROM mtree_node" );
	rs = ps.executeQuery();
	rs.next();
	newpos = rs.getInt(1) + 1;
	print("mtree_node.pos: " +  String.valueOf(newpos));
 
	// корневая запись запись в mtree_node
	ps = con.prepareStatement( "insert into mtree_node (parent_node, mtree_id, type, pos) values (0, ?, 'root', ?)" );
	ps.setInt( 1, mttId );
	ps.setInt( 2, newpos );
	rs = ps.executeUpdate();
	print("insert into mtree_node (parent_node, mtree_id, type, pos)" + 
          "VALUES (0," + String.valueOf(mttId) +	",'root'," + String.valueOf(newpos) +")");
 
	// услуга
	ps = con.prepareStatement( "insert into mtree_node (parent_node, mtree_id, type, data) values (LAST_INSERT_ID(), ?, 	'service', ?)" );
	ps.setInt( 1, mttId );
	ps.setInt( 2, service_id );
	rs = ps.executeUpdate();
	print("insert into mtree_node (parent_node, mtree_id, type, data)" + 
          "values (LAST_INSERT_ID()," + String.valueOf(mttId) +	",'service'," + String.valueOf(INTERNET_SERVICE_ID) +")");
 
	cid = event.getContractID();
	cm = new ContractManager(con);
	contract = cm.getContractByID(cid);
	cpu = new ContractParamUtils( con );
	// Получить стоимость из глобального тарифного плана "_Подключение", если физик
	if (contract.getFc() == 0)
	{
		ps = con.prepareStatement( "SELECT data FROM mtree_node WHERE id=?" );
		ps.setInt( 1, cost_node );
  	 	rs = ps.executeQuery();
		rs.next();
		cost = rs.getString(1);
	}
	// стоимость равна нулю, если юрик
	else
	{
		cost = "cost&0.0%col&1";
	}
 
	// Установить стоимость
	ps = con.prepareStatement( "insert into mtree_node (parent_node, mtree_id, type, data) values (LAST_INSERT_ID(), ?, 	'cost', ?)" );
	ps.setInt( 1, mttId );
	ps.setString( 2, cost );
	rs = ps.executeUpdate();
	print("insert into mtree_node (parent_node, mtree_id, type, data)" + 
         "values (LAST_INSERT_ID()," + String.valueOf(mttId) +	",'cost','" + String.valueOf(cost) +"')");
 
	// Прописать стоимость в параметре договора
	Pattern pattern = Pattern.compile("cost&(\\d+)\\.\\d+%");
	Matcher matcher = pattern.matcher(cost);
	try{
		if (matcher.find())
		{
			costValue = matcher.group(1);
			cpu.setStringParam( cid, PID_CONNECT_COST, costValue );
		}
	} catch (Exception exception) {
		error("Get connection cost:" + exception.getMessage());
	}
}
 
 
//_________________________________________________________________________________________________________
 
 
cid = event.getContractID();
 
 
ptm =  new PersonalTariffManager( con );
csm = new ContractServiceManager( con );
msu = new ModuleAndServiceUtils( con );
// ищем услуги в модуле RSCM
inetConnect = false;    
phoneConnect = false;    
services = msu.getContractService(cid, RSCM_ID);
for ( int i = 0; i < services.size() ; i++ )
{
	service = services.get(i);
	if (service.getId() == INTERNET_SERVICE_ID) 
	{
		inetConnect = true;
	}
	if (service.getId() == PHONE_SERVICE_ID) 
	{
		phoneConnect = true;
	}
}
 
// Интернет
if (inetConnect)
{
	createPT("Подключение - Интернет", INTERNET_COST_NODE, INTERNET_SERVICE_ID);
}
 
// Телефон
if (phoneConnect)
{
	createPT("Подключение - Телефон", PHONE_COST_NODE, PHONE_SERVICE_ID);
}

Событие "Договор создан" (Приостановка договора)

import bitel.billing.server.script.bean.event.*;
import bitel.billing.server.contract.bean.*; 
 
cid = event.getContractID();
contract = event.getContract();
print(contract);
 
csm = new ContractStatusManager(con);
 
cs = new ContractStatus();
cs.setContractId(cid); 
cs.setDate1(contract.getDate1());
cs.setStatus(4); 
 
csm.changeStatus(cs);

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

import bitel.billing.server.contract.bean.*;
 
//Группа ожидания оплаты подключения
GROUP_EP = 17;
//Группа ожидания подключения
GROUP_EC = 18;
//Параметр, в котором прописана дата начала предоставления услуг
PARAM_START_DATE = 49;
 
cid = event.getContractID(); 
contract = new ContractManager(con).getContractByID(cid);
contract_groups = contract.getGroups();
contract_param_utils = new ContractParamUtils( con );
contract_is_group_ep = (contract_groups & (1L<<GROUP_EP)) > 0;
contract_is_group_ec = (contract_groups & (1L<<GROUP_EC)) > 0;
contract_start_date = contract_param_utils.getDateParam( cid, PARAM_START_DATE );
 
if (contract_start_date == null && !contract_is_group_ep && !contract_is_group_ec)
{
	event.addAction( 15, "Добавить договор в очередь \"ожидание оплаты подключения\"" );
};
if (contract_start_date == null && !contract_is_group_ec)
{
	event.addAction( 16, "Добавить договор в очередь \"ожидание подключения\"" );
};

Событие "Обработка доп. действия для договора" (Добавление договора в очередь "Ожидание оплаты подключения")

import java.sql.*;
import java.util.*;
 
import bitel.billing.server.contract.bean.*;
if (event.getActionId() != 15) 
{ 
	print("skipped");
	return; 
}
 
//Группа ожидания оплаты подключения
GROUP_EP = 17;
 
cid = event.getContractID(); 
contract = new ContractManager(con).getContractByID(cid);
contract_groups = contract.getGroups();
 
contract_groups = contract_groups | 1L<<GROUP_EP;
query = "UPDATE contract SET gr=? WHERE id=?";
psUpdate = con.prepareStatement( query );
psUpdate.setLong( 1, contract_groups );
psUpdate.setInt( 2, cid );
psUpdate.executeUpdate();

Событие "Обработка доп. действия для договора" (Добавление договора в очередь "Ожидание подключения")

import java.sql.*;
import java.util.*;
 
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.contract.object.bean.*;
import ru.bitel.bgbilling.plugins.crm.server.dao.*;
import ru.bitel.bgbilling.plugins.crm.common.model.*;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
 
 
private getObject (cid)
{
	object_manager = new ObjectManager(con);
	contract_objects = object_manager.getObjectList(cid);
	for( ContractObject object : contract_objects )
	{
		return object.getId(); 
	};
	return null;
}
private getTargetDate()
{
	day = 0;
	if (contract_fc == 0){
		day = 60;
	};
	if (contract_fc == 1){
		day = 14;
	};
	CalendarTargetDate = Calendar.getInstance();
	CalendarTargetDate.add( Calendar.DAY_OF_YEAR, day );
	TargetDate = new Date(CalendarTargetDate.getTime().getTime());
	return TargetDate;
}
private getTaskType()
{
	if (contract_type == 1){
		return 3;
	};
	if (contract_type == 2){
		return 4;
	};
}
private getTaskGroup()
{
	return 3;
}
private GetCRMComment()
{
	query_crm_comment = "SELECT comment FROM contract_comment WHERE LOWER(subject) LIKE '%crm%' AND cid='"+cid+"';";
	ps_crm_comment = con.prepareStatement(query_crm_comment);
	rs_crm_comment = ps_crm_comment.executeQuery();
	if ( rs_crm_comment.next() )
	{
		return rs_crm_comment.getString(1);
	}
	else
	{
		return "Задача создана автоматически";
	}
}
 
if (event.getActionId() != 16) 
{ 
	print("skipped");
	return; 
}
 
//Группа ожидания оплаты подключения
GROUP_EP = 17;
//Группа ожидания подключения
GROUP_EC = 18;
//Группа Интернет
GROUP_INTERNET = 14;
//Группа Телефония
GROUP_PHONE = 7;
 
EventDate = new Date();
cid = event.getContractID(); 
contract = new ContractManager(con).getContractByID(cid);
contract_firma = contract.getFirmID();
contract_groups = contract.getGroups();
contract_type = 0;
// contract_type = 1 - интернет
// contract_type = 2 - телефония
if ((contract_groups & (1L<<GROUP_INTERNET)) > 0)
{
	contract_type = 1;
}
else if ((contract_groups & (1L<<GROUP_PHONE)) > 0)
{
	contract_type = 2;
}
else
{
	return;
};
contract_fc = contract.getFc();
contract_groups = contract_groups & ~(1L<<GROUP_EP);
contract_groups = contract_groups | 1L<<GROUP_EC;
query = "UPDATE contract SET gr=? WHERE id=?";
psUpdate = con.prepareStatement( query );
psUpdate.setLong( 1, contract_groups );
psUpdate.setInt( 2, cid );
psUpdate.executeUpdate();
 
//Ищем задачу на подключение
filter = new RegisterTaskManager.TaskFilter();
filter.cid = cid;
filter.types = Integer.toString(getTaskType());
register_task_manager = new RegisterTaskManager( con );
task_count = register_task_manager.getTaskCount(filter);
object = getObject(cid);
if (task_count == 0 && object != null){
	RegisterTask task = new RegisterTask();
	task.setContractID( cid );
	task.setTypeID(  getTaskType() );
	task.setGroupID( getTaskGroup() );
	task.setOpenUserID( 0 ) ;
	task.setOpenTime( EventDate );
	task.setComment( GetCRMComment() );
	task.setAddressParamID( 2 );
	task.setAddressObjectId( object );
	task.setTargetDate(getTargetDate());
	register_task_manager.updateTask( "new", task );
};


Событие "Приход платежа" (Проверка оплаты подключения)

import java.sql.*;
import java.util.*;
 
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.util.*;
import bitel.billing.server.contract.object.bean.*;
import ru.bitel.bgbilling.plugins.crm.server.dao.*;
import ru.bitel.bgbilling.plugins.crm.common.model.*;
import bitel.billing.server.model.*;
 
private getObject (cid)
{
	object_manager = new ObjectManager(con);
	contract_objects = object_manager.getObjectList(cid);
	for( ContractObject object : contract_objects )
	{
		return object.getId(); 
	};
	return null;
}
private getTargetDate()
{
	day = 0;
	if (contract_fc == 0){
		day = 60;
	};
	if (contract_fc == 1){
		day = 14;
	};
	CalendarTargetDate = Calendar.getInstance();
	CalendarTargetDate.add( Calendar.DAY_OF_YEAR, day );
	TargetDate = new Date(CalendarTargetDate.getTime().getTime());
	return TargetDate;
}
private getTaskType()
{
	if (contract_type == 1){
		return 3;
	};
	if (contract_type == 2){
		return 4;
	};
}
private getTaskGroup()
{
	return 3;
}
 
private GetCRMComment()
{
	query_crm_comment = "SELECT comment FROM contract_comment WHERE LOWER(subject) LIKE '%crm%' AND cid='"+cid+"';";
	ps_crm_comment = con.prepareStatement(query_crm_comment);
	rs_crm_comment = ps_crm_comment.executeQuery();
	if ( rs_crm_comment.next() )
	{
		return rs_crm_comment.getString(1);
	}
	else
	{
		return "Задача создана автоматически";
	}
}
 
 
//Параметр, в котором прописана стоимость подключения
PARAM_CONNECT_PAY = 46;
//Группа ожидания оплаты подключения
GROUP_EP = 17;
//Группа ожидания подключения
GROUP_EC = 18;
//Группа Интернет
GROUP_INTERNET = 14;
//Группа Телефония
GROUP_PHONE = 7;
 
EventDate = new Date();
cid = event.getContractID();
contract = new ContractManager(con).getContractByID(cid);
contract_firma = contract.getFirmID();
contract_groups = contract.getGroups();
contract_type = 0;
// contract_type = 1 - интернет
// contract_type = 2 - телефония
if ((contract_groups & (1L<<GROUP_INTERNET)) > 0)
{
	contract_type = 1;
}
else if ((contract_groups & (1L<<GROUP_PHONE)) > 0)
{
	contract_type = 2;
}
else
{
	return;
};
contract_fc = contract.getFc();
contract_param_utils = new ContractParamUtils( con );
contract_balance_utils = new BalanceUtils(con);
contract_balance = contract_balance_utils.getBalance (EventDate, cid);
contract_limit = contract.getBalanceLimit();
 
if ((contract_groups & (1L<<GROUP_EP)) > 0)
{
	//Проверяем оплатили подключение или нет
	connect_pay = Double.parseDouble(contract_param_utils.getStringParam( cid, PARAM_CONNECT_PAY ));
	if (connect_pay > 0 && contract_balance >= connect_pay)
	{
		//Клиент оплатил, можно делать!!!
		contract_groups = contract_groups & ~(1L<<GROUP_EP);
		contract_groups = contract_groups | 1L<<GROUP_EC;
		query = "UPDATE contract SET gr=? WHERE id=?";
		psUpdate = con.prepareStatement( query );
		psUpdate.setLong( 1, contract_groups );
		psUpdate.setInt( 2, cid );
		psUpdate.executeUpdate();
 
		//Ищем задачу на подключение
		filter = new RegisterTaskManager.TaskFilter();
		filter.cid = cid;
		filter.types = Integer.toString(getTaskType());
		register_task_manager = new RegisterTaskManager( con );
		task_count = register_task_manager.getTaskCount(filter);
		object = getObject(cid);
		if (task_count == 0 && object != null){
			RegisterTask task = new RegisterTask();
			task.setContractID( cid );
			task.setTypeID(  getTaskType() );
			task.setGroupID( getTaskGroup() );
			task.setOpenUserID( 0 ) ;
			task.setOpenTime( EventDate );
			task.setComment( GetCRMComment() );
			task.setAddressParamID( 2 );
			task.setAddressObjectId( object );
			task.setTargetDate(getTargetDate());
			register_task_manager.updateTask( "new", task );
		};		
	}
	else
	{
		register_task_manager = new RegisterTaskManager( con );
		object = getObject(cid);
		RegisterTask task = new RegisterTask();
		task.setContractID( cid );
		task.setTypeID(  11 );
		task.setGroupID( 6 );
		task.setOpenUserID( 0 ) ;
		task.setOpenTime( EventDate );
		task.setComment( "Недостаточная оплата.\nТекущий баланс: "+contract_balance+"\nСтоимость подключения: " + connect_pay);
		task.setAddressParamID( 2 );
		task.setAddressObjectId( object );
		task.setTargetDate( EventDate );
		register_task_manager.updateTask( "new", task );
 
};


Продолжение следует...

Личные инструменты