Скрипт проверки баланса и отключения договора
Материал из BiTel WiKi
(Различия между версиями)
DimOn (Обсуждение | вклад) (доделал и выложил снова) |
Angelwhy (Обсуждение | вклад) |
||
(2 промежуточные версии не показаны) | |||
Строка 258: | Строка 258: | ||
--[[Участник:DimOn|dimOn]] 07:34, 10 декабря 2009 (UTC) | --[[Участник:DimOn|dimOn]] 07:34, 10 декабря 2009 (UTC) | ||
+ | |||
+ | |||
+ | В связи с тем, что в 5.1 событие-таймер для этих целей лучше не использовать, переделал скрипт приведенный выше, который добавляется в глобальные скрипты поведения и выполняется задачей "Выполнение глабальных скриптов по таймеру". | ||
+ | <source lang="java"> | ||
+ | |||
+ | 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); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | </source> | ||
+ | --[[Участник:Angelwhy|Angelwhy]] 11:15, 20 января 2011 (UTC) |
Текущая версия на 11:16, 20 января 2011
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)