Поиск и изменение статусов у договоров
Материал из BiTel WiKi
(Различия между версиями)
KostiK (Обсуждение | вклад) |
KostiK (Обсуждение | вклад) |
||
Строка 4: | Строка 4: | ||
И по завершении отправляется email с id договоров, у которых был изменен статус. | И по завершении отправляется email с id договоров, у которых был изменен статус. | ||
(скрипт написан для 5.1) | (скрипт написан для 5.1) | ||
+ | <source lang="java"> | ||
+ | import java.util.*; | ||
+ | import java.math.*; | ||
+ | import bitel.billing.server.util.*; | ||
+ | import bitel.billing.common.*; | ||
+ | import ru.bitel.bgbilling.kernel.contract.status.server.*; | ||
+ | import ru.bitel.bgbilling.kernel.contract.status.common.bean.*; | ||
+ | import ru.bitel.common.model.*; | ||
+ | |||
+ | //Нам необходимо реализовать периодическое закрытие договоров, которые не закрываются текущей задачей планировщика "Закрытие статуса Npay договоров" и уходят в минус, по определённым критериям. | ||
+ | //Задолженность по времени равна или больше N месяцев или сумма задолженности превышает N месячных наработок. Какие есть пути реализации этой задачи? штатно/нештатно, может уже есть подобные решения? | ||
+ | //Да, логика там подходит, если я устанавливаю число 90 "дней и более" и сальдо от -1000000 до -1, то, после среза балансов, я вижу нужные мне договора. | ||
+ | //Но нужно смену статуса на "Закрыт" у этих договоров делать ежедневно, без автоматизации этого процесса никак. | ||
+ | //Желательно высылать оповещение у нас есть специальная почта bgbilling@seven-sky.net, или, если возможно, настравиваемый е-майл. | ||
+ | |||
+ | StringBuilder contractIds= new StringBuilder(); | ||
+ | |||
+ | public void changeStatus( List list, WSContractStatusMonitorImpl ws ) | ||
+ | { | ||
+ | //массив с id договоров | ||
+ | int[] cids = new int[list.size()]; | ||
+ | int i = 0; | ||
+ | for( MonitorStatusResult m : list ) | ||
+ | { | ||
+ | cids[i] = m.getCid(); | ||
+ | contractIds.append( "contractId = " ); | ||
+ | contractIds.append( m.getCid() ); | ||
+ | contractIds.append( "\n" ); | ||
+ | i ++; | ||
+ | } | ||
+ | //с какой даты начиает действовать статус | ||
+ | Date dateTo = new Date(); | ||
+ | //по какую дату начинает действовать статус | ||
+ | Date dateFrom = new Date(); | ||
+ | |||
+ | String comment = " изменен в скрипте "; | ||
+ | //id статуса | ||
+ | int statusId = 0; | ||
+ | //собственно изменение статуса | ||
+ | ws.changeContractStatus( cids, statusId, dateFrom, dateTo, comment ); | ||
+ | |||
+ | } | ||
+ | public void sendEmail( MailMsg msg ) | ||
+ | { | ||
+ | String m = "Статусы были изменены у следующих договоров : \n"; | ||
+ | m += contractIds.toString(); | ||
+ | //отправка письма ( кому, заголовок письма, тело письма ) | ||
+ | msg.sendMessage( "bgbilling@seven-sky.net", "Change status in contracts", m ); | ||
+ | } | ||
+ | |||
+ | public void main( setup, con, conSlave ) | ||
+ | { | ||
+ | print( "Start ..." ); | ||
+ | WSContractStatusMonitorImpl ws = new WSContractStatusMonitorImpl(); | ||
+ | MailMsg msg = new MailMsg( setup ); | ||
+ | ws.setConnection(con); | ||
+ | ws.setSetup( setup ); | ||
+ | try | ||
+ | { | ||
+ | print("Create balans dump start ..."); | ||
+ | //делаем срез баланса | ||
+ | ws.createBalanceDump(); | ||
+ | print("Create balans dump finish !"); | ||
+ | } | ||
+ | catch(BGException e) | ||
+ | { | ||
+ | print("Ошибка при создании среза балансов \n"); | ||
+ | print( e.getMessage() ); | ||
+ | return; | ||
+ | } | ||
+ | // ------------ ОПИСАНИЕ ПЕРЕМЕННЫХ ДЛЯ ПОИСКА ДОГОВОРОВ------------------- | ||
+ | // переменные аналогичны галочкам, выпадающим спискам в мониторе статуса | ||
+ | |||
+ | /*Переменная отвечающая за режим. Значения могут быть | ||
+ | -1 - все | ||
+ | 0 - кредит | ||
+ | 1 - дебет | ||
+ | */ | ||
+ | int mode = -1; | ||
+ | |||
+ | /*Переменная отвечающая за количество дней или месяцев, соответствует полю ввода после "Находится в статусе:" | ||
+ | Значение может быть любым целым числом. | ||
+ | */ | ||
+ | int statusPeriod = 0 ; | ||
+ | |||
+ | /*Переменная отвечающая за тип statusPeriod дни или месяцы. Соответствует выпадающему списку после "Находится в статусе:" | ||
+ | Значение может быть: | ||
+ | day - дней или более | ||
+ | month - месяцев или более | ||
+ | */ | ||
+ | String statusPeriodUnit = "day"; | ||
+ | |||
+ | /*Переменная отвечающая за выбранные группы. Соответствует закладке "Группы". | ||
+ | Значение: | ||
+ | id групп договоров. их можно посмотреть в справочнике. | ||
+ | Заполнять аналогичным способом, как показано ниже | ||
+ | Если заполнять не требуется просто удалить срочки вида group.add(id); | ||
+ | */ | ||
+ | Set group = new HashSet(); | ||
+ | group.add(53); | ||
+ | |||
+ | /* Переменная отвечающая за выбранные группы. Соответствует закладке "Искл. группы". | ||
+ | Значения и заполнение аналогично как и для переменной group | ||
+ | */ | ||
+ | Set notGroup = new HashSet(); | ||
+ | |||
+ | /* Переменная отвечающая за выбранные статусы. Соответствует галочкам около названий статусов | ||
+ | Значения могут быть: | ||
+ | -1 - ниодин статус не выбран. ОБЯЗАТЕЛЬНО УКАЗЫВАТЬ | ||
+ | 0 - подключен, | ||
+ | 1 - на отключении, | ||
+ | 2 - отключен, | ||
+ | 3 - закрыт, | ||
+ | 4 - приостановлен, | ||
+ | 5 - на подключении | ||
+ | Заполнять аналогичным способом как показано ниже | ||
+ | */ | ||
+ | String status = "-1,0,1,2,3,4,5"; | ||
+ | |||
+ | /* Переменная отвечающая за значение Сальдо. Соответствует полю ввода "Сальдо от" | ||
+ | Значение может быть любым числом. Если значение не нужно, то оставить пустую строку "" */ | ||
+ | String saldoFrom = ""; | ||
+ | |||
+ | /* Переменная отвечающая за значение Сальдо. Соответствует полю ввода "Сальдо до" | ||
+ | Значение может быть любым числом. Если значение не нужно, то оставить пустую строку "" */ | ||
+ | String saldoTo = ""; | ||
+ | |||
+ | /* Переменная отвечающая за сортировку договоров в листе. Соответствует выпадающему списку "Сортировка:" | ||
+ | Значения могут быть: | ||
+ | saldo - сортировка по сумме задолженности | ||
+ | contract.status_date сортировка с какой даты | ||
+ | contract.title сортировка по номеру договора | ||
+ | contract.comment сортировка по комментарию договора | ||
+ | Если значение не нужно, то оставить пустую строку "". | ||
+ | */ | ||
+ | String sort =""; | ||
+ | |||
+ | /* Переменная отвечающая за вкючение в поиск суб договоров с зависимым балансом. Соответствует галочке "Субдоговора" | ||
+ | Значения могут быть: | ||
+ | 0 - не включать в поиск субдоговора | ||
+ | 1 - включать в поиск | ||
+ | */ | ||
+ | int subContract = 0; | ||
+ | |||
+ | /* Страницы. Тут будем использовать их для того, чтобы не ело много памяти. | ||
+ | 0 - с какой страницы. | ||
+ | 25 - кол-во записей на странице | ||
+ | */ | ||
+ | Page page = new Page(0,25); | ||
+ | |||
+ | /* Переменная отвечающая за кол-во предыдущих месяцев по которым будет смотреться наработка . Соответствует полю ввода после "наработке за" | ||
+ | Значение может быть любым целым числом. По умолчанию 0 | ||
+ | */ | ||
+ | int saldoAccountMonths = 0; | ||
+ | |||
+ | /* | ||
+ | Переменная отвечающая за значение сальдо. Соответствует полю ввода после галочки "-сальдо больше на" | ||
+ | Значение может быть любым числом. По умолчанию 0 | ||
+ | */ | ||
+ | BigDecimal saldoAcconuntsMore = BigDecimal.ZERO; | ||
+ | |||
+ | /* | ||
+ | Переменная отвечающая за услуги по которым будет проверяться наработка. Соответствует списку услуг. При этом необходмо чтобы значение переменной serviceMaxVal было отлично от значения по умолчанию | ||
+ | Заполнение, аналогично передыдущим переменным такого же типа. | ||
+ | Значения - id услуг. | ||
+ | */ | ||
+ | Set serviceAccountMaxServices = new HashSet(); | ||
+ | |||
+ | /* | ||
+ | Переменная отвечающая за верхнюю границу значения наработки по услугам за прошлый и текущий месяцы. Соответствует полю ввода в списке услуг "Наработка по услугам за прошлый и текущий месяц <=" | ||
+ | Значение может быть любое число с плавающей точкой. По умолчанию -1 | ||
+ | */ | ||
+ | float serviceMaxVal = -1f; | ||
+ | |||
+ | /* | ||
+ | Переменная отвечающая за галочку баланс < лимита. | ||
+ | Значения могут быть | ||
+ | 0 - не отмечена | ||
+ | 1 - отмечена | ||
+ | */ | ||
+ | int balanceLimit = 0; | ||
+ | |||
+ | /* | ||
+ | Переменная отвечаюшая за галочку баланс на начало месяца < лимита | ||
+ | Значения могу быть | ||
+ | 0 - не отмечена | ||
+ | 1 - отмечена | ||
+ | */ | ||
+ | int balancePrevLimit = 0; | ||
+ | |||
+ | try | ||
+ | { | ||
+ | print("Search contracts and change status start..."); | ||
+ | // ищем договора удовлетворяющие условию | ||
+ | Result res = ws.contractSearch( mode, statusPeriod, statusPeriodUnit, group, notGroup, status, saldoFrom, saldoTo, sort, subContract, page, saldoAccountMonths, saldoAcconuntsMore, | ||
+ | serviceAccountMaxServices, serviceMaxVal, balanceLimit, balancePrevLimit ); | ||
+ | print( "Кол-во страниц = " + res.getPage().getPageCount() ); | ||
+ | //сохраняем страницы | ||
+ | page = res.getPage(); | ||
+ | //меняем статусы у первой партии | ||
+ | changeStatus( res.getList(), ws ); | ||
+ | // по кол-ву страниц бегаем берем по 25(или сколько указали выше) записей и изменяем у них статусы | ||
+ | for( int i = 1; i < page.getPageCount(); i ++ ) | ||
+ | { | ||
+ | res = ws.contractSearch( mode, statusPeriod, statusPeriodUnit, group, notGroup, status, saldoFrom, saldoTo, sort, subContract, page, saldoAccountMonths, saldoAcconuntsMore, | ||
+ | Set<Integer> serviceAccountMaxServices, serviceMaxVal, balanceLimit, balancePrevLimit ); | ||
+ | changeStatus( res.getList(), ws ); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | catch( BGException e ) | ||
+ | { | ||
+ | print("Ошибка при поиске и изменении статуса договоров \n"); | ||
+ | print( e.getMessage() ); | ||
+ | return; | ||
+ | } | ||
+ | print("Search contracts and change status finish !"); | ||
+ | print("Send email !"); | ||
+ | //отпрвка письма | ||
+ | sendEmail(msg); | ||
+ | |||
+ | |||
+ | print("Finish!!!"); | ||
+ | } | ||
+ | |||
+ | </source> |
Версия 14:08, 1 декабря 2011
Скрипт работает с API монитора статуса. Поиск договоров происходит так же как и в мониторе статуса. Указываются различные переменные и значения. Далее происходит изменение статусов у найденных договоров. И по завершении отправляется email с id договоров, у которых был изменен статус. (скрипт написан для 5.1)
import java.util.*; import java.math.*; import bitel.billing.server.util.*; import bitel.billing.common.*; import ru.bitel.bgbilling.kernel.contract.status.server.*; import ru.bitel.bgbilling.kernel.contract.status.common.bean.*; import ru.bitel.common.model.*; //Нам необходимо реализовать периодическое закрытие договоров, которые не закрываются текущей задачей планировщика "Закрытие статуса Npay договоров" и уходят в минус, по определённым критериям. //Задолженность по времени равна или больше N месяцев или сумма задолженности превышает N месячных наработок. Какие есть пути реализации этой задачи? штатно/нештатно, может уже есть подобные решения? //Да, логика там подходит, если я устанавливаю число 90 "дней и более" и сальдо от -1000000 до -1, то, после среза балансов, я вижу нужные мне договора. //Но нужно смену статуса на "Закрыт" у этих договоров делать ежедневно, без автоматизации этого процесса никак. //Желательно высылать оповещение у нас есть специальная почта bgbilling@seven-sky.net, или, если возможно, настравиваемый е-майл. StringBuilder contractIds= new StringBuilder(); public void changeStatus( List list, WSContractStatusMonitorImpl ws ) { //массив с id договоров int[] cids = new int[list.size()]; int i = 0; for( MonitorStatusResult m : list ) { cids[i] = m.getCid(); contractIds.append( "contractId = " ); contractIds.append( m.getCid() ); contractIds.append( "\n" ); i ++; } //с какой даты начиает действовать статус Date dateTo = new Date(); //по какую дату начинает действовать статус Date dateFrom = new Date(); String comment = " изменен в скрипте "; //id статуса int statusId = 0; //собственно изменение статуса ws.changeContractStatus( cids, statusId, dateFrom, dateTo, comment ); } public void sendEmail( MailMsg msg ) { String m = "Статусы были изменены у следующих договоров : \n"; m += contractIds.toString(); //отправка письма ( кому, заголовок письма, тело письма ) msg.sendMessage( "bgbilling@seven-sky.net", "Change status in contracts", m ); } public void main( setup, con, conSlave ) { print( "Start ..." ); WSContractStatusMonitorImpl ws = new WSContractStatusMonitorImpl(); MailMsg msg = new MailMsg( setup ); ws.setConnection(con); ws.setSetup( setup ); try { print("Create balans dump start ..."); //делаем срез баланса ws.createBalanceDump(); print("Create balans dump finish !"); } catch(BGException e) { print("Ошибка при создании среза балансов \n"); print( e.getMessage() ); return; } // ------------ ОПИСАНИЕ ПЕРЕМЕННЫХ ДЛЯ ПОИСКА ДОГОВОРОВ------------------- // переменные аналогичны галочкам, выпадающим спискам в мониторе статуса /*Переменная отвечающая за режим. Значения могут быть -1 - все 0 - кредит 1 - дебет */ int mode = -1; /*Переменная отвечающая за количество дней или месяцев, соответствует полю ввода после "Находится в статусе:" Значение может быть любым целым числом. */ int statusPeriod = 0 ; /*Переменная отвечающая за тип statusPeriod дни или месяцы. Соответствует выпадающему списку после "Находится в статусе:" Значение может быть: day - дней или более month - месяцев или более */ String statusPeriodUnit = "day"; /*Переменная отвечающая за выбранные группы. Соответствует закладке "Группы". Значение: id групп договоров. их можно посмотреть в справочнике. Заполнять аналогичным способом, как показано ниже Если заполнять не требуется просто удалить срочки вида group.add(id); */ Set group = new HashSet(); group.add(53); /* Переменная отвечающая за выбранные группы. Соответствует закладке "Искл. группы". Значения и заполнение аналогично как и для переменной group */ Set notGroup = new HashSet(); /* Переменная отвечающая за выбранные статусы. Соответствует галочкам около названий статусов Значения могут быть: -1 - ниодин статус не выбран. ОБЯЗАТЕЛЬНО УКАЗЫВАТЬ 0 - подключен, 1 - на отключении, 2 - отключен, 3 - закрыт, 4 - приостановлен, 5 - на подключении Заполнять аналогичным способом как показано ниже */ String status = "-1,0,1,2,3,4,5"; /* Переменная отвечающая за значение Сальдо. Соответствует полю ввода "Сальдо от" Значение может быть любым числом. Если значение не нужно, то оставить пустую строку "" */ String saldoFrom = ""; /* Переменная отвечающая за значение Сальдо. Соответствует полю ввода "Сальдо до" Значение может быть любым числом. Если значение не нужно, то оставить пустую строку "" */ String saldoTo = ""; /* Переменная отвечающая за сортировку договоров в листе. Соответствует выпадающему списку "Сортировка:" Значения могут быть: saldo - сортировка по сумме задолженности contract.status_date сортировка с какой даты contract.title сортировка по номеру договора contract.comment сортировка по комментарию договора Если значение не нужно, то оставить пустую строку "". */ String sort =""; /* Переменная отвечающая за вкючение в поиск суб договоров с зависимым балансом. Соответствует галочке "Субдоговора" Значения могут быть: 0 - не включать в поиск субдоговора 1 - включать в поиск */ int subContract = 0; /* Страницы. Тут будем использовать их для того, чтобы не ело много памяти. 0 - с какой страницы. 25 - кол-во записей на странице */ Page page = new Page(0,25); /* Переменная отвечающая за кол-во предыдущих месяцев по которым будет смотреться наработка . Соответствует полю ввода после "наработке за" Значение может быть любым целым числом. По умолчанию 0 */ int saldoAccountMonths = 0; /* Переменная отвечающая за значение сальдо. Соответствует полю ввода после галочки "-сальдо больше на" Значение может быть любым числом. По умолчанию 0 */ BigDecimal saldoAcconuntsMore = BigDecimal.ZERO; /* Переменная отвечающая за услуги по которым будет проверяться наработка. Соответствует списку услуг. При этом необходмо чтобы значение переменной serviceMaxVal было отлично от значения по умолчанию Заполнение, аналогично передыдущим переменным такого же типа. Значения - id услуг. */ Set serviceAccountMaxServices = new HashSet(); /* Переменная отвечающая за верхнюю границу значения наработки по услугам за прошлый и текущий месяцы. Соответствует полю ввода в списке услуг "Наработка по услугам за прошлый и текущий месяц <=" Значение может быть любое число с плавающей точкой. По умолчанию -1 */ float serviceMaxVal = -1f; /* Переменная отвечающая за галочку баланс < лимита. Значения могут быть 0 - не отмечена 1 - отмечена */ int balanceLimit = 0; /* Переменная отвечаюшая за галочку баланс на начало месяца < лимита Значения могу быть 0 - не отмечена 1 - отмечена */ int balancePrevLimit = 0; try { print("Search contracts and change status start..."); // ищем договора удовлетворяющие условию Result res = ws.contractSearch( mode, statusPeriod, statusPeriodUnit, group, notGroup, status, saldoFrom, saldoTo, sort, subContract, page, saldoAccountMonths, saldoAcconuntsMore, serviceAccountMaxServices, serviceMaxVal, balanceLimit, balancePrevLimit ); print( "Кол-во страниц = " + res.getPage().getPageCount() ); //сохраняем страницы page = res.getPage(); //меняем статусы у первой партии changeStatus( res.getList(), ws ); // по кол-ву страниц бегаем берем по 25(или сколько указали выше) записей и изменяем у них статусы for( int i = 1; i < page.getPageCount(); i ++ ) { res = ws.contractSearch( mode, statusPeriod, statusPeriodUnit, group, notGroup, status, saldoFrom, saldoTo, sort, subContract, page, saldoAccountMonths, saldoAcconuntsMore, Set<Integer> serviceAccountMaxServices, serviceMaxVal, balanceLimit, balancePrevLimit ); changeStatus( res.getList(), ws ); } } catch( BGException e ) { print("Ошибка при поиске и изменении статуса договоров \n"); print( e.getMessage() ); return; } print("Search contracts and change status finish !"); print("Send email !"); //отпрвка письма sendEmail(msg); print("Finish!!!"); }