Организация системы отслеживания и отключения КТВ должников на BGBS с использованием CRM плагина

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

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

// В зависимости от квартала клиента // возможна передача различных групп решения int getTaskGroup() {

   quarter = "";
   
   query = 
       "SELECT quarter.title FROM contract_parameter_type_2 AS cp  " +
       " LEFT JOIN address_house AS house ON cp.hid=house.id  " +
       " LEFT JOIN  address_quarter AS quarter ON house.quarterid=quarter.id " +
       " WHERE cp.cid=? AND cp.pid=?";
   ps = con.prepareStatement( query );
   
   ps.setInt( 1, cid );
   ps.setInt( 2, TASK_ADDRESS_PARAM );
   
   rs = ps.executeQuery();
   if( rs.first() ) {
       quarter = rs.getString( 1 );
   }
   result = 0;
   if( guarter.equals( "1" ) )
   {
      result = GROUP_1;   
   }
   else
   {
      result = GROUP_2;
   }
     
   return result;

}

// коды групп решения задач GROUP_1 = 1; GROUP_2 = 2;

DISCONNECT_TASK = 3; CALL_TASK = 23;

CONNECT_TASK = 24;

TASK_ADDRESS_PARAM = 9; GROUP_DOLG = 15;

// коды параметров договора ФИО и Телефон FIO_PARAM = "1"; PHONE_PARAM = 2;

DEBT_FIX_PARAM = 34;

DEBT_LIMIT = 260; // минимальная сумма баланса, после которой подключать BALANCE_BORDER = 164.99f;

cpu = new ContractParamUtils( con ); contractManager = new ContractManager( con ); taskManager = new RegisterTaskManager( con ); bu = new BalanceUtils( con );

balance = bu.getBalance( time, cid ); contract = contractManager.getContractByID( cid );

dolgGroup = (contract.getGroups() & (1<<GROUP_DOLG) ) > 0; print( "dolg group => " + dolgGroup );

// оплатил должник - можно подлкючать if( dolgGroup && balance > BALANCE_BORDER ) {

     // есть не закрытая задача "подключение должника"
     connectTask = false;
     filter = new RegisterTaskManager.TaskFilter();
     filter.types =  String.valueOf( CONNECT_TASK );
     filter.cid = cid;
     activeTasks = taskManager.getNoClosedTaskList( cid );
     for( RegisterTask task : activeTasks )
     {
        // задача не закрыта либо закрыта но не обработана 
        if( task.getStatus() != RegisterTask.STATUS_CLOSED ||
            !task.isProcessed() )
        {
            connectTask = true;
            print( "1" );
            break;
        } 
     }
     print( "connectTask => " + connectTask );
      // создание задачи на подключение
     if( !connectTask )
     {
        RegisterTask task = new RegisterTask(); 
        task.setContractID( cid );
        task.setTypeID(  CONNECT_TASK );
        groupId = getTaskGroup();
        
        task.setGroupID( groupId );
        task.setOpenUserID( 0 ) ;
        task.setOpenTime( event.getGenerateTime() );
        task.setComment( "" );
        task.setAddressParamID( TASK_ADDRESS_PARAM );
        taskManager.updateTask( "new", task );          
         //отправка письма на почту
         filter = new RegisterTaskManager.TaskFilter();
         filter.id = task.getID();
         filter.fioParams = FIO_PARAM;
         filter.phoneParam = PHONE_PARAM;
         filter.processed = -1;
          filter.orders = new ArrayList(); 
         
         print( "filter = " + filter + "; taskManager = " + taskManager );
         
         personalTask = taskManager.getTaskList( filter, new Page( 1, 1 ) ).get( 0 );
         
         message = new StringBuffer( 300 );
         message.append( contract.getTitle() );
         message.append( " " );
         message.append( personalTask.getStreet() );
         message.append( " " );
         message.append( personalTask.getHouse() );
         message.append( " " );  
         message.append( personalTask.getFlat() );
          
         new MailMsg( setup ).sendMessageEx( "disp@disp.com", "Оплатил должник", message.toString(), "text/plain" );
         //
         print( "Sending to mail.." );
     }

} // работающий клиент else {

 if( balance <= - ( DEBT_LIMIT - 1 ) )
 {
  print( "it's debt" );
  return;
 }
  
 // закрытие активных задач на дозвон и отключение должника
 List activeTasks = taskManager.getNoClosedTaskList( cid );
 for( RegisterTask task : activeTasks )
 {
    // собственно закрытие таких задач
    if( ( task.getTypeID() == DISCONNECT_TASK && task.getStatus() == RegisterTask.STATUS_OPEN  )  ||  
         (task.getTypeID() == CALL_TASK && task.getStatus() != RegisterTask.STATUS_CLOSED ) )
    {
        task.setResolution(  task.getResolution() + "\nОплатил " +  TimeUtils.formatDate( time ) );
      
        task.setCloseUserID( 0 );
        task.setCloseTime( time );
        task.setExecuteDate( time );
        task.setGroupID( DEFAULT_GROUP );
     
        task.setStatus( RegisterTask.STATUS_CLOSED );
       
        taskManager.updateTask( String.valueOf( task.getID() ), task );       
        print( "Closing DISCONNECT and CALL task: " + task.getID() );
    }
   
    // если принятая задача на отключение - отправка письма
    if( task.getTypeID() == DISCONNECT_TASK && task.getStatus() == RegisterTask.STATUS_ACCEPTED  )
    {

print( "The task already has an ACCEPTED status." );

         //отправка письма на почту
         filter = new RegisterTaskManager.TaskFilter();
         filter.id = task.getID();
         filter.fioParams = FIO_PARAM;
         filter.phoneParam = PHONE_PARAM;
         filter.processed = -1;
         filter.orders = new ArrayList(); 
         
         personalTask = taskManager.getTaskList( filter, new Page( 1, 1 ) ).get( 0 );
        
         message = new StringBuffer( 300 );
         message.append( personalTask.getStreet() );
         message.append( " " );
         message.append( personalTask.getHouse() );
         message.append( " " );  
         message.append( personalTask.getFlat() );
         message.append( " " );  
         message.append( personalTask.getContract() );  
          
         new MailMsg( setup ).sendMessageEx( "disp@disp.com", "Оплатил отключаемый", message.toString(), "text/plain" );
      
         print( "Send message Pay in disconnect" );
    }    
 }
     
 print( "Deleting debt fix date.." );
 cpu.deleteDateParam( cid,  DEBT_FIX_PARAM );

} </source>

Для не оплативших в течении указанного количества дней после выполненной задачи обзвона должников создаются задачи на Отключение должника. Они могут быть распечатаны в виде нарядов монтажникам, для чего используется шаблон отчета журнала задач Отчет по подключению (файл выложен выше в статье). Этот же шаблон можно использовать при создании нарядов на подключение.

Задачи на отключения

Выполненные задачи помечаются выполненными и обрабатываются оператором. При обработке задач отрабатывает скрипт для задач типа Подключение должника и Отключение должника.

import java.sql.*;
import java.util.*;
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.util.*;
import ru.bitel.bgbilling.plugins.crm.server.dao.*;
import ru.bitel.bgbilling.plugins.crm.common.model.*;
import bitel.billing.server.model.*;
 
DISCONNECT_TASK = 3;
CONNECT_TASK = 24;
 
// группа должник
GROUP_DOLG = 15;
// группа "пенсионер"
GROUP_PENS = 34;
 
// код услуги "абонплата"
SERVICE_PAY  = 2;
// код услуги "абонплата долг"
SERVICE_PAY_DOLG = 3;
// код услуги "абонплата пенсионеров"
SERVICE_PAY_PENS = 8;
 
// код расхода "за повторное включение"
RECONNECT_CHARGE = 5;
DEBT_FIX_PARAM = 34; 
// сумма расхода за повторное включение
RECONNECT_SUM = 75;
 
BALANCE_BORDER = 164.99f;
ADDRESS_PARAM = 9;
 
FIO_PARAM = "1";
PHONE_PARAM = 2;
 
cid = event.getContractID();
task = event.getTask();
 
// В зависимости от квартала клиента 
//  возможна передача различных групп решения
int getTaskGroup() {
    quarter = "";
 
    query = 
        "SELECT quarter.title FROM contract_parameter_type_2 AS cp  " +
        " LEFT JOIN address_house AS house ON cp.hid=house.id  " +
        " LEFT JOIN  address_quarter AS quarter ON house.quarterid=quarter.id " +
        " WHERE cp.cid=? AND cp.pid=?";
    ps = con.prepareStatement( query );
 
    ps.setInt( 1, cid );
    ps.setInt( 2, TASK_ADDRESS_PARAM );
 
    rs = ps.executeQuery();
    if( rs.first() ) {
        quarter = rs.getString( 1 );
    }
 
    result = 0;
 
    if( guarter.equals( "1" ) )
    {
       result = GROUP_1;   
    }
    else
    {
       result = GROUP_2;
    }
 
    return result;
}
 
// коды групп решения задач
GROUP_1 = 1;
GROUP_2 = 2;
 
report = event.getReport();
 
serviceManager = new ContractServiceManager( con );
cu = new ContractUtils( con );
cpu = new ContractParamUtils( con );
chm =  new ChargeManager( con );
contractManager = new ContractManager( con );
bu = new BalanceUtils( con );
taskManager = new RegisterTaskManager( con );
 
if( task.getTypeID() != DISCONNECT_TASK &&  task.getTypeID() != CONNECT_TASK ) 
{
 print( "This task type does't processing.." );
 return;
}
 
if( task.getStatus() != RegisterTask.STATUS_CLOSED )
{
 report.append( cu.getContractTitle( cid, true ) );
 report.append( " => задача не закрыта\n" );
 return;
}
 
Calendar date = task.getExecuteDate();
if( date == null )
{
 report.append( cu.getContractTitle( cid, true ) );
 report.append( " => не установлена дата исполнения\n" );
 
  error( "executeDate == null" );
  return;
}
 
beforeDay = task.getExecuteDate().clone();
beforeDay.add( Calendar.DAY_OF_YEAR, -1 );
 
// перечень услуг на дату
services = serviceManager.getContractServiceList( cid, date );
 
contract = contractManager.getContractByID( cid );
 
dolgGroup = (contract.getGroups() & (1<<GROUP_DOLG) ) > 0;
print( "dolg group => " + dolgGroup );
 
pensGroup = (contract.getGroups() & (1L<<GROUP_PENS) ) > 0;
print( "pens group => " + pensGroup );
 
// отключение должника
if( task.getTypeID() == DISCONNECT_TASK )
{
     if( dolgGroup )     
     {
           report.append( cu.getContractTitle( cid, true ) );
           report.append( " => у договора уже стоит группа долг\n" );
 
           return; 
     }
 
     for( ContractService service : services )
     {
          // закрытие абонплаты  
          if( service.getServiceID() == SERVICE_PAY || service.getServiceID() == SERVICE_PAY_PENS )
          {
                 service.setDate2( beforeDay );
                 serviceManager.updateContractService( String.valueOf( service.getID() ), service );
          }  
     } 
 
     // открытие абонплаты "долг"
    cs = new ContractService();
    cs.setContractID( cid );
    cs.setServiceID( SERVICE_PAY_DOLG );
    cs.setDate1( task.getExecuteDate() );
    cs.setComment( "Установлена скриптом" );
 
    serviceManager.updateContractService( "new", cs );
 
    // установка группы "долг" 
    cpu.setGroup( cid,  GROUP_DOLG  );
 
     // если баланс позволяет - сразу открытие задачи "Подключение должника"
     balance = bu.getBalance(  new GregorianCalendar(), cid );
 
     print( "balance=" + balance );
 
     if( balance >= BALANCE_BORDER )
     {
        // есть не закрытая задача "подключение должника"
       connectTask = false;
 
        List activeTasks = taskManager.getNoClosedTaskList( cid );
        for( RegisterTask task : activeTasks )
        {
 		print( "task type: " + task.getTypeID() ) ;
           if( task.getTypeID() == CONNECT_TASK  )
           {
               connectTask = true;
               break;
           }
        }
 
        print( "connectTask => " + connectTask );
         // создание задачи на подключение
        if( !connectTask )
        {
           task = new RegisterTask(); 
           task.setContractID( cid );
           task.setTypeID(  CONNECT_TASK );
           task.setGroupID( getTaskGroup() );
           task.setOpenUserID( 0 ) ;
           task.setOpenTime( event.getGenerateTime() );
           task.setComment( "" );
           task.setAddressParamID( ADDRESS_PARAM );
 
           taskManager.updateTask( "new", task );
 
            report.append( cu.getContractTitle( cid, true ) );
            report.append( " => создана задача на подключение\n" );
 
            //отправка письма на почту
            filter = new RegisterTaskManager.TaskFilter();
            filter.id = task.getID();
            filter.fioParams = FIO_PARAM;
            filter.phoneParam = PHONE_PARAM;
            filter.processed = -1;
            filter.orders = new ArrayList(); 
 
            personalTask = taskManager.getTaskList( filter, new Page( 1, 1 ) ).get( 0 );
 
            message = new StringBuffer( 300 );
            message.append( personalTask.getStreet() );
            message.append( " " );
            message.append( personalTask.getHouse() );
            message.append( " " );  
            message.append( personalTask.getFlat() );
            message.append( " " );  
            message.append( personalTask.getContract() );  
 
            new MailMsg( setup ).sendMessageEx( "bill@ufanet.ru;disp@ufanet.ru;setks@ufanet.ru", "Оплатил отключенный", message.toString(), "text/plain" );
 
            print( "Send message Pay in disconnect process" );
 
        } 
    }
}
// подключение должника
else if( task.getTypeID() == CONNECT_TASK )
{
      if( !dolgGroup )     
     {
           report.append( cu.getContractTitle( cid, true ) );
           report.append( " => у договора нет группы долг\n" );
 
           return; 
     }
 
     for( ContractService service : services )
     {
          // закрытие абонплаты  "долг"
          if( service.getServiceID() == SERVICE_PAY_DOLG )
          {
                 service.setDate2( beforeDay );
                 serviceManager.updateContractService( String.valueOf( service.getID() ), service );
          }  
     } 
 
     // открытие абонплаты
    cs = new ContractService();
    cs.setContractID( cid );
    if( pensGroup )
    {
       cs.setServiceID( SERVICE_PAY_PENS );
    }
    else
    {
       cs.setServiceID( SERVICE_PAY );
    }
    cs.setDate1( task.getExecuteDate() );
    cs.setComment( "Установлена скриптом" );
 
    serviceManager.updateContractService( "new", cs );
 
    // снятие расхода за повторное подключение
    charge = new Charge();
    charge.setContractID( cid ); 
    charge.setChargeTypeID( RECONNECT_CHARGE );
    charge.setSumma( RECONNECT_SUM );
    charge.setDate( task.getExecuteDate() );
    charge.setComment( "Установлена скриптом" );
 
    chm.updateCharge( "new", charge );
 
    print( "setting charge" );
 
    bu.updateBalance( task.getExecuteDate(), cid );
 
    // сброс группы "Должник" 
    cpu.unsetGroup( cid,  GROUP_DOLG  ); 
    cpu.deleteDateParam( cid,  DEBT_FIX_PARAM );
}
 
task.setProcessed( true );

Когда клиент отключен за долг у него устанавливается абонплата Долг с нулевой ценой. Разумного требованию этому нет, сделано с точки зрения аналитики базы. При обработке задач скрипт выдает отчет по ошибкам и нестыковкам оператору.

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