Скрипт проверки баланса и отключения договора
Материал из BiTel WiKi
import java.sql.*; import java.util.*; import java.math.*; import bitel.billing.server.contract.bean.*; import bitel.billing.server.tariff.*; import bitel.billing.server.util.*; import bitel.billing.common.KernelConst; import bitel.billing.server.script.bean.event.*; import ru.bitel.bgbilling.plugins.crm.server.dao.*; import ru.bitel.bgbilling.plugins.crm.common.model.*; /* Данный скрипт приостанавливает статус договра, когда исходящий остаток ниже абонентской платы. Просьба изменить скрипт, то есть отвязать его от абонентской платы и приостанавливать договор по исходящему балансу <-1000>, но при этом учитывать лимит. Если например у договора стоит лимит <-1200>, а баланс меньше <-1000>, но больше <-1200> то с такими договорами ни чего не делаем и приостанавливаем их только по достижению баланса меньше <-1200>. Также в скрипт добавить работу с кредитовыми договрами. Когда договор приостановлен, то заносим в параметр договора (код 28, тип параметра "Дата") дату пристановления договора "Дата фиксации долга". Приостановленный договр добавлем в группу договоров "Должники" (код 8). Далее в CRM создаем задачу на обзвон должников (тип задачи 1), группа решений (ID 3) с комментарием "Приостановлен сервером за долг". +надо ещё удалить параметр "Дата погашения долга" */ /* Приход платежа Для договоров, входящих к группу "Должники", при приходе платежа делается проверка. Если при внесение платежа баланс стал больше 0 (нуля), то удаляем дату приостановления договора "Дата фиксации долга" (код 28, тип параметра "Дата") в параметре договора, создаем "Дата погашения долга" (код 20, тип параметра "Дата"). Закрываем в CRM задачу на обзвон должников с комментарием "Долг оплачен". Исключаем из группы договоров "Должники" (код 8). */ // группы, для которых будет работать скрипт (номера) int[] GROUPS ={29,1,2}; // значение порога, до которого лимит не действует (в рублях) BigDecimal LIMITVALUE = new BigDecimal( -10 ); // ид параметра договора "Дата фиксации долга" int DATE_OFF_PID = 30; // ид параматра даты включения, "Дата погашения долга" int DATE_ON_PID = 27; //Группа "Недостаточно средств" int GROUP_ERROR_BALANCE = 19; // CRM - тип задачи int CRM_TYPE = 3; // CRM - группа решений int CRM_GR = 3; // если при внесении платежа баланс стал больше этой цифры, то делаем действия BigDecimal LIMIT_TO_ON = new BigDecimal( -100 ); //---------- /** * Договор в одной ли из групп. Возвращается номер группы, в которой договор. * Или -1, если договор ни в одной из групп. */ int contractInGroup( Contract contract, int[] groups ) { for( int i=0; i<groups.length; i++ ) { if( (contract.getGroups() & (1L<<groups[i])) != 0 ) { return groups[i]; } } return -1; } BalanceUtils bu = new BalanceUtils( con ); ContractParamUtils cpu = new ContractParamUtils( con ); ContractStatusManager contract_status_manager = new ContractStatusManager( con ); RegisterTaskManager rtm = new RegisterTaskManager(con); int cid = event.getContractID(); Calendar time = event.getGenerateTime(); Calendar DateNow = Calendar.getInstance(); Contract contract = new ContractManager(con).getContractByID(cid); if (contract == null) { print("договор не найден! пропускаем."); return; } else { print("=> договор: "+contract.getTitle()); } // проверям на вхождение в заданные группы int cigr = contractInGroup( contract, GROUPS ); if (cigr == -1) { print("договор не входит в нужные группы! пропускаем."); return; } else { print("договор входит в группу #" + cigr); } // статус получаем status = contract_status_manager.getStatus(cid, DateNow); contract_status = KernelConst.CONTRACT_STATUS_ACTIVE; if (status != null) { contract_status = status.getStatus(); } if (contract_status == null) { contract_status = KernelConst.CONTRACT_STATUS_ACTIVE; } // получаем баланс contract_balance = bu.getBalance (time.getTime(), cid); print("баланс договора: "+contract_balance); // если событие таймера if( event instanceof bitel.billing.server.script.bean.event.TimerEvent && event.getFlag() == 1 ) { // проверяем статус // Пропускаем не активные договора if (contract_status != KernelConst.CONTRACT_STATUS_ACTIVE) { print("договор не активен! пропускаем."); return; } // берём лимит BigDecimal limit = contract.getBalanceLimit(); print("лимит: "+limit); // может, надо поставить новый лимит? limit = limit.min(LIMITVALUE); print("значение по которому проверяем: "+limit); // соравниваем с лимитом if( contract_balance.compareTo( limit ) >= 0 ) { print("баланс хороший"); } else { print("баланс плохой"); // суспендим договор ContractStatus status = new ContractStatus(); status.setContractId( cid ); status.setDate1( DateNow ); status.setDate2( null ); status.setStatus( KernelConst.CONTRACT_STATUS_SUSPENDED ); status.setComment( "Недостаточно средств" ); contract_status_manager.changeStatus( status, 0 ); // ставим в аттрибут договора дату отключения cpu.setDateParam( cid, DATE_OFF_PID, time.getTime(), 0 ); print( "off-date: " + TimeUtils.formatDate( time ) ); // удаляем дату включения (если есть) cpu.deleteDateParam( cid, DATE_ON_PID, 0 ); // заносим в группу contract_groups = contract.getGroups(); contract_groups = contract_groups | 1L<<GROUP_ERROR_BALANCE; psUpdate = con.prepareStatement( "UPDATE contract SET gr=? WHERE id=?" ); psUpdate.setLong( 1, contract_groups ); psUpdate.setInt( 2, cid ); psUpdate.executeUpdate(); // Далее в CRM создаем задачу на обзвон должников (тип задачи 1), // группа решений (ID 3) с комментарием "Приостановлен сервером за долг". RegisterTask task = new RegisterTask(); task.setComment("Приостановлен сервером за долг"); task.setContractID(cid); task.setCreateTime(time.getTime()); task.setCreateUserID(0); task.setOpenTime(time.getTime()); task.setOpenUserID(0); task.setGroupID(CRM_GR); task.setStatus(RegisterTask.STATUS_OPEN); task.setTypeID(CRM_TYPE); rtm.updateTask(task); } } // если событие прихода платежа if( event instanceof bitel.billing.server.script.bean.event.PaymentEvent ) { // проверяем на вхождение в группу "должники" long contract_groups = contract.getGroups(); if ((contract_groups & (1L<<GROUP_ERROR_BALANCE)) == 0) { print("договор не входит в группу \"должники\"! пропускаем."); return; } // сравниваем с лимитом if( contract_balance.compareTo( LIMIT_TO_ON ) > 0 ) { print("баланс хороший (>"+LIMIT_TO_ON.toPlainString()+")"); // удаляем из группы contract_groups = contract_groups & ~(1L<<GROUP_ERROR_BALANCE); psUpdate = con.prepareStatement( "UPDATE contract SET gr=? WHERE id=?" ); 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( "Автоматически после оплаты" ); contract_status_manager.changeStatus( status, 0 ); } // ставим в аттрибут договора дату включения cpu.setDateParam( cid, DATE_ON_PID, time.getTime(), 0 ); print( "on-date: " + TimeUtils.formatDate( time ) ); // удаляем дату выключения cpu.deleteDateParam( cid, DATE_OFF_PID, 0 ); // Закрываем в CRM задачу на обзвон должников с комментарием "Долг оплачен". List tasks = rtm.getNoClosedTaskList(cid); for( int i=0; i<tasks.size(); i++ ) { RegisterTask task = (RegisterTask)tasks.get( i ); if ( task.getGroupID()==CRM_GR && task.getTypeID()==CRM_TYPE ) { print("найдена CRM-задача #"+task.getID()+". закрываем."); // закрываем задачу task.setStatus(RegisterTask.STATUS_CLOSED); task.setCloseTime(time.getTime()); task.setCloseUserID(0); task.setComment("Долг оплачен"); rtm.updateTask(task); } } } else { print("баланс плохой (<="+LIMIT_TO_ON.toPlainString()+"). пропускаем."); } }
Для 5.0. Привязать к событиям "приход платежа" и "таймер"
--dimOn 07:34, 10 декабря 2009 (UTC)
В связи с тем, что в 5.1 событие-таймер для этих целей лучше не использовать, переделал скрипт приведенный выше, который добавляется в глобальные скрипты поведения и выполняется задачей "Выполнение глабальных скриптов по таймеру".
import java.sql.*; import java.util.*; import java.math.*; import bitel.billing.server.contract.bean.*; import bitel.billing.server.tariff.*; import bitel.billing.server.util.*; import bitel.billing.common.KernelConst; import bitel.billing.server.script.bean.event.*; import ru.bitel.bgbilling.plugins.crm.server.dao.*; import ru.bitel.bgbilling.plugins.crm.common.model.*; public void main( setup, con, conSlave ) { // группы, для которых будет работать скрипт (номера) int[] GROUPS ={5,6,8}; // значение порога, до которого лимит не действует (в рублях) BigDecimal LIMITVALUE = new BigDecimal( -10 ); // ид параметра договора "Дата фиксации долга" int DATE_OFF_PID = 22; // ид параматра даты включения, "Дата погашения долга" int DATE_ON_PID = 23; //Группа "Недостаточно средств" int GROUP_ERROR_BALANCE = 9; // CRM - тип задачи int CRM_TYPE = 1; // CRM - группа решений int CRM_GR = 1; // если при внесении платежа баланс стал больше этой цифры, то делаем действия BigDecimal LIMIT_TO_ON = new BigDecimal( -100 ); int[] usl ={0,2}; //---------- /** * Договор в одной ли из групп. Возвращается номер группы, в которой договор. * Или -1, если договор ни в одной из групп. */ int contractInGroup( Contract contract, int[] groups ) { for( int i=0; i<groups.length; i++ ) { if( (contract.getGroups() & (1L<<groups[i])) != 0 ) { return groups[i]; } } return -1; } BalanceUtils bu = new BalanceUtils( con ); ContractParamUtils cpu = new ContractParamUtils( con ); ContractStatusManager contract_status_manager = new ContractStatusManager( con ); RegisterTaskManager rtm = new RegisterTaskManager(con); String sql = "SELECT id FROM contract"; PreparedStatement ps = con.prepareStatement( sql ); ResultSet rs = ps.executeQuery(); while(rs.next()) { int cid = rs.getInt( 1 ); //print ("cid:"+cid); Calendar DateNow = Calendar.getInstance(); Contract contract = new ContractManager(con).getContractByID(cid); if (contract == null) { // print("Dogovor ne nayden. Propuskaem"); continue; } else { // print("=> dogovor: "+contract.getTitle()); } // проверям на вхождение в заданные группы int cigr = contractInGroup( contract, GROUPS ); if (cigr == -1) { // print("Dogovor ne vhodit v nujnie gruppi. Propuskaem."); continue ; } else { // print("Dogovor vhodit v gruppu #" + cigr); } // статус получаем status = contract_status_manager.getStatus(cid, DateNow.getTime()); contract_status = KernelConst.CONTRACT_STATUS_ACTIVE; if (status != null) { contract_status = status.getStatus(); } if (contract_status == null) { contract_status = KernelConst.CONTRACT_STATUS_ACTIVE; } // получаем баланс contract_balance = bu.getBalance (DateNow.getTime(), cid); //print("Balans dogovora: "+contract_balance); // проверяем статус // Пропускаем не активные договора if (contract_status != KernelConst.CONTRACT_STATUS_ACTIVE) { print("Dogovor ne activen. Propuskaem"); continue; } // берём лимит BigDecimal limit = contract.getBalanceLimit(); //print("limit: "+limit); // может, надо поставить новый лимит? //limit = limit.min(LIMITVALUE); //narabotka = bu.getSaldo (time.getTime(), cid); // print("Znachenie po kotoromu propuskaem: "+limit); // соравниваем с лимитом if( contract_balance.compareTo( limit )>= 0) { // print("Баланс horoshiy"); } else { // print("Баланс plohoy"); // суспендим договор ContractStatus status = new ContractStatus(); status.setContractId( cid ); status.setDateFrom( DateNow.getTime() ); status.setDateTo( null ); status.setStatus( KernelConst.CONTRACT_STATUS_DISCONNECTED ); status.setComment( "Недостаточно средств" ); contract_status_manager.changeStatus( status, 0 ); // ставим в аттрибут договора дату отключения cpu.setDateParam( cid, DATE_OFF_PID, DateNow.getTime(), 0 ); // print( "off-date: " + TimeUtils.formatDate( DateNow ) ); // удаляем дату включения (если есть) cpu.deleteDateParam( cid, DATE_ON_PID, 0 ); // заносим в группу contract_groups = contract.getGroups(); contract_groups = contract_groups | 1L<<GROUP_ERROR_BALANCE; psUpdate = con.prepareStatement( "UPDATE contract SET gr=? WHERE id=?" ); psUpdate.setLong( 1, contract_groups ); psUpdate.setInt( 2, cid ); psUpdate.executeUpdate(); // Далее в CRM создаем задачу на обзвон должников (тип задачи 1), // группа решений (ID 3) с комментарием "Приостановлен сервером за долг". RegisterTask task = new RegisterTask(); task.setComment("Приостановлен сервером за долг"); task.setContractID(cid); task.setCreateTime(DateNow.getTime()); task.setCreateUserID(0); task.setOpenTime(DateNow.getTime()); task.setOpenUserID(0); task.setGroupID(CRM_GR); task.setStatus(RegisterTask.STATUS_OPEN); task.setTypeID(CRM_TYPE); rtm.updateTask(task); } } }
--Angelwhy 11:15, 20 января 2011 (UTC)