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

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

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

Внимание!!

Решение устарело, т.к. плагин CRM более не поддерживается. Для решения подобных задач рекомендуем использовать BGCRM. Организация отключения должников КТВ

Ставится задача автоматического массового выявления, оповещения и отключения должников по КТВ.

В планировщике заданий добавляем генерацию события таймера. Событие генерируется каждые сутки в 0 часов 1 минуту.

Настройка задачи в планировщике

Общий алгоритм работы следующий:

  1. Раз в месяц по таймеру запускается задача выявления должников. В параметрах договоров-должников проставляется дата фиксации долга и создается задача на обзвон должников.
  2. Далее производится обзвон (либо разнос квитанций), задачи помечаются выполненными и обрабатываются.
  3. Следюущая обработка события таймера зафиксировав выполненную задачу обзвона и констатировав, что долг еще есть - создает задачу на отключение должника.
  4. При обработке задачи отключения должника автоматически закрывается абонентская плата, устанавливается группа договора долг.

Типы задач:

  1. Отключение должника (код 3 в данном примере)
  2. Обзвон должника (код 23 в данном примере)
  3. Подключение должника (код 24 в данном примере)

Необходимые параметры договора:

  1. Адрес, тип Адрес (код 9) в данном примере
  2. Дата фиксации долга, тип Дата (код 34 в данном примере)

Необходимые группы договоров:

  1. Должник - пометка договора, октлюченного за долг (код группы 15 в данном примере)

В справочнике групп решения CRM могут быть определены одна или несколько групп, группа может определяться в зависимости от номера квартала. В данном примере есть две группы решения с кодами 1 и 2.

В меню Автоматизация=>Скрипты поведения добавляем обработчик данного события.

import java.sql.*;
import java.util.*;
 
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.script.bean.event.*;
import bitel.billing.server.util.*;
import ru.bitel.bgbilling.plugins.crm.server.dao.*;
import ru.bitel.bgbilling.plugins.crm.common.model.*;
 
// В зависимости от квартала клиента 
//  возможна передача различных групп решения
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;
 
// код параметра договора "Дата фиксации долга"   
DEBT_FIX_PARAM = 34; 
 
TASK_ADDRESS_PARAM = 9;
// сколько дней ждать после обзвона   
DAYS_AFTER_CALL = 3;
// группа "Должник"
GROUP_DOLG = 15;
// группы "ЕРКЦ", "Условно расторгнут", "VIP" - договора с такими группами не наблюдаются
GROUP_ERKC = 43;
GROUP_USL_RAST = 21;
GROUP_VIP = 12;
 
// размер ежемесячного платежа (абонплаты) обычного
MONTHLY_CHARGE = 130;
// размер ежемесячного платежа (абонплаты) уменьшенного
MONTHLY_CHARGE_CHEAP = 105;
// дата подлкючения к ЕРКЦ
ERKC_ACTIVE_DATE_PARAM = 52;
 
cid = event.getContractID();
time = event.getGenerateTime();
 
print( "cid=" + cid );
 
// проверка флага события таймера, обрабатываем только события с флагом = 1
if( event.getFlag() != 1 ) {
    print( "Flag != 1, skipping.." );
    return;
}
 
bu = new BalanceUtils( con );   
rtm = new RegisterTaskManager( con );
cm = new ContractManager( con );
cpu = new ContractParamUtils( con );
tm = new ContractTariffManager( con );
 
contract = cm.getContractByID( cid );
 
// Проверки ---------------------------------------------------------------------------------------------------------------
 
// Договора ЕРКЦ не контролируются на долги, ЕРКЦ занимается этим сам
erkcGroup = ( contract.getGroups() & (1L<<GROUP_ERKC) ) > 0;
 
if( erkcGroup ) {
    print( "erkc group" );
    erkcActiveDate = cpu.getDateParam( cid, ERKC_ACTIVE_DATE_PARAM );
    if ( erkcActiveDate == null ) {
        error( "ERKC Activation Date is not set" );
        return;
    }
    else {
        if ( time.before( erkcActiveDate ) ) {
            print( "ERKC is not yet activated. Activation date: " + erkcActiveDate.get( Calendar.DAY_OF_MONTH ) + "." + ( erkcActiveDate.get( Calendar.MONTH ) + 1 ) + "." + erkcActiveDate.get( Calendar.YEAR ) );
        }
        else {
            print( "ERKC activated. No debts controlled" );
            //return;
        }
    }
}
 
// Условно расторгнутые
uslRastorg = ( contract.getGroups() & (1L<<GROUP_USL_RAST) ) > 0;
if( uslRastorg ) {
    print( "usl rastorg group" );
    return;
}
 
// Должники
dolgGroup = ( contract.getGroups() & (1L<<GROUP_DOLG) ) > 0;
if( dolgGroup ) {
    print( "dolg group" );
    return;
}
 
// VIP-клиенты
vipGroup = ( contract.getGroups() & (1L<<GROUP_VIP) ) > 0;
if( vipGroup ) {
    print( "vip group" );
    return;
}
 
// Кредитные договора
if( contract.getBalanceMode() == Contract.CREDIT_BALANCE_MODE ) {
    print( "credit mode" );
    return;
}
 
// Конец проверок ---------------------------------------------------------------------------------------------------------
 
debt = false;
float balance = bu.getBalance( time, cid );
 
// Выбираем лимит под тариф
tp = tm.getContractTariff( cid, time );
if( tp == null ) {
    error("no active tariff plans" );
    return;
}
tpid = tp.getTariffPlanID();
 
switch( tpid ) {
    case 10:
      monthlyCharge = MONTHLY_CHARGE;
      break;
    case 12:
      monthlyCharge = MONTHLY_CHARGE_CHEAP;
      break;
    case 14:
      monthlyCharge = MONTHLY_CHARGE_CHEAP;
      break;
    default:
      monthlyCharge = MONTHLY_CHARGE;
      break;
}
 
// до 20-го числа за должников считаем тех, у кого баланс меньше 3-х абонок,
// после 20-го -- меньше 2-х абонок
if( time.get( Calendar.DATE ) < 20 ) {
    print("do 20");
    if( balance < - 3 * monthlyCharge + .01 ) {
        debt = true;
    }
}
else {
    print("posle 20");
    if( balance < - 2 * monthlyCharge + .01 ) {
        debt = true;
    }
}
 
if( erkcGroup ) {
	if( balance < - 6 * monthlyCharge + .01 ) {
		debt = true;
		print( "Debug ERKC < 6 month debt" );
	}
}
 
if( !debt ) {   
    return;
}
 
 
fixDate = cpu.getDateParam( cid, DEBT_FIX_PARAM );
if( fixDate == null ) {
   fixDate = (Calendar)time.clone();
   cpu.setDateParam( cid, DEBT_FIX_PARAM, fixDate );
}
 
print(  "fixDate=" +  TimeUtils.formatDate( fixDate ) );
 
callTask = null;
disconnectTask = null;
 
// список задач после даты фиксции долга
taskList = rtm.getAfterDateTaskList( cid, fixDate );
for( RegisterTask task : taskList )
{
   // найдена задача на обзвон 
   if( task.getTypeID() == CALL_TASK )
   {
     callTask = task;
   }
   // найдена задача на отключение 
   if( task.getTypeID() == DISCONNECT_TASK )
   {
     disconnectTask = task;
   }
}
 
print( "callTask = " + callTask + "; disconnectTask = " + disconnectTask );
 
// долг есть а задачи на обзвон нет - создание задачи на обзвон
if( callTask == null )
{
   callTask = new RegisterTask();    
 
   callTask.setContractID( cid );
   callTask.setAddressParamID( TASK_ADDRESS_PARAM );
 
   callTask.setOpenTime( time );
   callTask.setOpenUserID( 0 );
 
   callTask.setTypeID( CALL_TASK );
   callTask.setComment( "Долг: " + Utils.formatCost( balance ) ) ;
 
   groupId = getTaskGroup();
   callTask.setGroupID( groupId );
 
   print( "creating call task" )  ;
   rtm.updateTask( "new", callTask );
}
// статус задачи открыт - обновляем информацию о долге в комментарии задачи
else if ( callTask.getStatus() == RegisterTask.STATUS_OPEN  ) {
    callTask.setComment( "Долг: " + Utils.formatCost( balance ) ) ;
    rtm.updateTask(  String.valueOf( callTask.getID() ), callTask ); 
}
// задача дозвона выполнена
else if ( callTask.getStatus() == RegisterTask.STATUS_CLOSED ) {
    // задачи на отключения нет
	if( erkcGroup ) {
		print( "For ERKC orders don't need taks for turn off" ) ;
		return;
	}
    if ( disconnectTask == null ) {
        // после обзвона прошел срок - создание задачи отключения
        if ( TimeUtils.daysDelta( callTask.getExecuteDate(), time ) >= DAYS_AFTER_CALL ) {
           disconnectTask = new RegisterTask();
 
           disconnectTask.setContractID( cid );
           disconnectTask.setAddressParamID( TASK_ADDRESS_PARAM );
 
           disconnectTask.setOpenTime( time );
           disconnectTask.setOpenUserID( 0 );
 
           disconnectTask.setTypeID( DISCONNECT_TASK );
 
           groupId = getTaskGroup();
           disconnectTask.setGroupID( groupId ); 
           disconnectTask.setComment( "Долг: " + Utils.formatCost( balance ) ) ;
 
           print( "creating disconnect task." );
           rtm.updateTask( "new", disconnectTask );
        }
    }
    // открыта задача на отключение - обновление информации о долге в комментарии задачи
    else if ( disconnectTask.getStatus() == RegisterTask.STATUS_OPEN ) {
        disconnectTask.setComment( "Долг: " + Utils.formatCost( balance ) ) ;
        rtm.updateTask(  String.valueOf( disconnectTask.getID() ), disconnectTask );
    }
}

Предполагаем, что событие таймера обработано в результате чего получено множество задач типа Обзвон должника.

Задачи обзвона должника

Возможен непосредственный обзвон должников либо генерация квитанций и разнос их по квартирам. Как показывает практика, второй метод более эффективен. Для генерации квитанций подобного вида:

Квитанции

вы можете использовать шаблон отчета по задачам Квитанции. Для получения отчета необходимо выбрать тип шаблона над левым верхним углом таблицы задач, далее сохранить его в HTML файл и печатать. Непосредственная печать из биллинга невозможна, т.к. встроенный HTML компанент JAVA плохо поддерживает CSS, который используется для разделения страниц.

Шаблоны отчетов по задачам прописываются в конфигурации сервера биллинга следующим образом:

register.task.report.format=register_tasks.xsl:Отчет по подключению;register_tasks_1.xsl:Отчет по обслуживанию;register_tasks_2.xsl:Отчет по должникам;register_tasks_3.xsl:Квитанции

Файлы шаблонов вы можете загрузить здесь: Медиа:ktv_debt_xsl.zip

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

import bitel.billing.server.contract.bean.*;
import bitel.billing.server.util.*;
import java.util.*;
import ru.bitel.bgbilling.plugins.crm.server.dao.*;
import ru.bitel.bgbilling.plugins.crm.common.model.*;
import bitel.billing.server.model.*;
 
cid = event.getContractID();
time = event.getGenerateTime(); 
 
// В зависимости от квартала клиента 
//  возможна передача различных групп решения
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 );
}

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

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

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

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 );

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

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