forum.bitel.ru
http://forum.bitel.ru/

[5.2]Скрипт обработки запроса учетного периода
http://forum.bitel.ru/viewtopic.php?f=44&t=7101
Страница 1 из 1

Автор:  Alex-XXI [ 13 авг 2012, 19:49 ]
Заголовок сообщения:  [5.2]Скрипт обработки запроса учетного периода

По умолчанию модуль Inet добавляет учетный период до конца месяца. Пытаюсь написать скрипт для обработки учетного периода для модуля Inet, который бы добавлял учетный период необходимой длины и заносил расход на договор. В яве не силен, натолкните на нужный путь. Этот скрипт при компиляции выдает:
Код:
/usr/local/server/dyn/inet_accounting_period.java:24: cannot find symbol
symbol  : method setAccountingPeriod(ru.bitel.bgbilling.modules.inet.api.common.bean.InetAccountingPeriod)
location: class ru.bitel.bgbilling.kernel.event.Event   inet_accounting_period.java   24   23


Код:
import ru.bitel.bgbilling.kernel.event.Event;
import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.sql.ConnectionSet;
import java.util.*;
import ru.bitel.bgbilling.modules.inet.api.common.bean.*;
import bitel.billing.server.util.*;

public class inet_accounting_period
   extends EventScriptBase
{
   @Override
   public void onEvent( Event event1, Setup setup2, ConnectionSet connectionSet3 )
      throws Exception
   {
      int cid = event1.getContractId();
      Calendar DateFrom = event1.getTime();
      Calendar DateTo = DateFrom;
      DateTo.add(Calendar.DAY_OF_YEAR, 30);
      InetAccountingPeriod iap = new InetAccountingPeriod();
      iap.setContractId(cid);
      iap.setDateFrom(TimeUtils.convertCalendarToDate(DateFrom));
      iap.setDateTo(TimeUtils.convertCalendarToDate(DateTo));
      event1.setAccountingPeriod(iap);
   }

}

Автор:  Amir [ 13 авг 2012, 20:10 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Beanshell похож, но java строже, нужно указывать типы и желательно указывать генерики (List<Integer>, а не просто List)
Код:
package ru.bitel.bgbilling.modules.inet.dyn.period;

import java.util.Calendar;

import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetAccountingPeriod;
import ru.bitel.bgbilling.modules.inet.api.server.event.InetAccountingPeriodActivateEvent;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.sql.ConnectionSet;
import bitel.billing.common.TimeUtils;

public class InetAccountingPeriodActivator
    extends EventScriptBase<InetAccountingPeriodActivateEvent>
{
   @Override
   public void onEvent( InetAccountingPeriodActivateEvent event, Setup setup, ConnectionSet connectionSet )
       throws Exception
   {
      int contractId = event.getContractId();

      InetAccountingPeriod accountingPeriod = new InetAccountingPeriod();
      accountingPeriod.setContractId( contractId );

      Calendar calendar = (Calendar)event.getTime().clone();

      // от начала дня
      TimeUtils.clear_HOUR_MIN_MIL_SEC( calendar );
      accountingPeriod.setDateFrom( calendar.getTime() );

      // плюс 30 дней
      calendar.add( Calendar.DATE, 30 );
      accountingPeriod.setDateTo( calendar.getTime() );

      event.setAccountingPeriod( accountingPeriod );
   }
}

Calendar не стоит просто так присваивать - при присваивании объект не копируется, а просто создается новая ссылка на тот же самый объект (как и в beanshell), т.е. не
Код:
Calendar DateFrom = event1.getTime();
Calendar DateTo = DateFrom;
а
Код:
Calendar DateFrom = (Calendar)event1.getTime().clone();
Calendar DateTo = (Calendar)DateFrom.clone();

Автор:  Amir [ 13 авг 2012, 20:13 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Код:
package ru.bitel.bgbilling.modules.inet.dyn.period;

import java.sql.Connection;
import java.util.Calendar;

import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetAccountingPeriod;
import ru.bitel.bgbilling.modules.inet.api.server.event.InetAccountingPeriodActivateEvent;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.sql.ConnectionSet;
import bitel.billing.common.TimeUtils;

public class InetAccountingPeriodActivator
    extends EventScriptBase<InetAccountingPeriodActivateEvent>
{
   @Override
   public void onEvent( InetAccountingPeriodActivateEvent event, Setup setup, ConnectionSet connectionSet )
       throws Exception
   {
      Connection con = connectionSet.getConnection();
      
      int contractId = event.getContractId();

      InetAccountingPeriod accountingPeriod = new InetAccountingPeriod();
      accountingPeriod.setContractId( contractId );

      Calendar calendar = (Calendar)event.getTime().clone();

      // от начала дня
      TimeUtils.clear_HOUR_MIN_MIL_SEC( calendar );
      accountingPeriod.setDateFrom( calendar.getTime() );

      // плюс 30 дней
      calendar.add( Calendar.DATE, 30 );
      accountingPeriod.setDateTo( calendar.getTime() );

      event.setAccountingPeriod( accountingPeriod );
   }
}

Автор:  Alex-XXI [ 14 авг 2012, 01:24 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Спасибо за помощь, буду допиливать скрипт дальше.

Автор:  Alex-XXI [ 14 авг 2012, 14:13 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

В соответствии с api на InetAccountingPeriod добавил в скрипт UserId, класс компилируется без ошибок, но результата нет - учетный период устанавливается до конца месяца. Подскажите куда должны писаться логи, единственное место где нашел какое-либо концы - mq.log accounting-сервера
Код:
08-14/12:05:09  INFO [event-proc-p-2-t-1] InetServRuntimeMap - Taked event: Event[ru.bitel.bgbilling.modules.inet.api.server.event.InetAccountingPeriodModifie
dEvent] moduleId: 1; pluginId: no; cid: 3; scid: -1; userId: 1; timestamp: 1344931509131
08-14/12:05:43  INFO [event-proc-p-2-t-1] InetServRuntimeMap - Taked event: Event[ru.bitel.bgbilling.modules.inet.api.server.event.InetAccountingPeriodModifie
dEvent] moduleId: 1; pluginId: no; cid: 3; scid: -1; userId: 0; timestamp: 1344931543671

Последняя версия класса:
Код:
package ru.bitel.bgbilling.modules.inet.dyn.period;

import java.sql.Connection;
import java.util.Calendar;

import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetAccountingPeriod;
import ru.bitel.bgbilling.modules.inet.api.server.event.InetAccountingPeriodActivateEvent;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.sql.ConnectionSet;
import bitel.billing.common.TimeUtils;

public class InetAccountingPeriodActivator
    extends EventScriptBase<InetAccountingPeriodActivateEvent>
{
   @Override
   public void onEvent( InetAccountingPeriodActivateEvent event, Setup setup, ConnectionSet connectionSet )
       throws Exception
   {
      Connection con = connectionSet.getConnection();
     
      int contractId = event.getContractId();
      int UserId = event.getUserId();
      print("contractId=");
      print(contractId);
      print("UserId=");
      print(UserId);

      InetAccountingPeriod accountingPeriod = new InetAccountingPeriod();
      accountingPeriod.setContractId( contractId );

      Calendar calendar = (Calendar)event.getTime().clone();

      // от начала дня
      TimeUtils.clear_HOUR_MIN_MIL_SEC( calendar );
      accountingPeriod.setDateFrom( calendar.getTime() );

      // плюс 30 дней
      calendar.add( Calendar.DATE, 30 );
      accountingPeriod.setDateTo( calendar.getTime() );

      accountingPeriod.setUserId(UserId);

      event.setAccountingPeriod( accountingPeriod );
//     event.setProcessed(true);
   }
}

Автор:  Amir [ 14 авг 2012, 14:17 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Скрипт поведения добавлен в договор?

Автор:  Alex-XXI [ 14 авг 2012, 15:48 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Скрипт добавлен в договор, а созданный java-класс добавлен в скрипт. В клиенте биллинга на вкладке логов выполнения скриптов поведения тоже пусто.

Автор:  Alex-XXI [ 16 авг 2012, 19:29 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Если кому-то понадобиться, вот готовый скрипт:
Код:
import java.sql.Connection;
import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetAccountingPeriod;
import ru.bitel.bgbilling.modules.inet.api.server.event.InetAccountingPeriodActivateEvent;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.sql.ConnectionSet;
import bitel.billing.common.TimeUtils;
import bitel.billing.server.contract.bean.*;
import java.util.*;


public class AccountingPeriod
    extends EventScriptBase<InetAccountingPeriodActivateEvent>
{
   @Override
   public void onEvent( InetAccountingPeriodActivateEvent event, Setup setup, ConnectionSet connectionSet )
       throws Exception
   {
      event.setProcessed(true);
      Connection con = connectionSet.getConnection();
     
      int cid = event.getContractId();
     int UserId = event.getUserId();
      float pay; //абонентская плата
      int dt; //длина учетного периода
      int sid = 5; //код услуги абонентская плата
      Calendar date = (Calendar)event.getTime().clone();
      TimeUtils.clear_HOUR_MIN_MIL_SEC(date);
      ContractTariffManager ctm = new ContractTariffManager(con);
      int tariff_id = ctm.getContractTariff(cid, date).getTariffPlanId(); //Получаем id тарифного плана
      BalanceUtils bu = new BalanceUtils(con);
      float balance = bu.getBalance(date, cid); //текущий баланс договора

      ContractManager cm = new ContractManager(con);
      Contract contract = new Contract();
      contract = cm.getContractByID(cid);
      float limit = contract.getLimit();

      switch (tariff_id) {
          case 4:  pay = 200; //тариф 1;
                   dt = 29;
                   break;
          case 5:  pay = 600; //тариф 2;
                   dt = 89;
                   break;
          default: error("Incorrect current tariff!");
                   return;
      }

      if(balance - limit < pay) {
         error("Not enough money to open a period!!");
         return;
      }
      else {
         bu.addContractAccount(cid, date, sid, pay); //добавляем наработку
         bu.setBalanceFromAccount(cid, date);
         bu.updateBalance(date, cid); // обновляем баланс

         InetAccountingPeriod accountingPeriod = new InetAccountingPeriod();
         accountingPeriod.setContractId(cid);
         accountingPeriod.setUserId(UserId);
         accountingPeriod.setDateFrom(date.getTime());
         date.add(Calendar.DATE, dt); //добавляем учетный период
         accountingPeriod.setDateTo(date.getTime());
         
         event.setAccountingPeriod(accountingPeriod);

      }

   }
}

Автор:  snark [ 21 авг 2012, 14:42 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

getBalance() возвращает BigDecimal, так почему бы прямо с ним и не работать? В 5.0 у меня так (ахтунг! биншел):
Код:
calendar = event.getRequestDate();
date     = calendar.getTime();

balance = new BalanceUtils(con).getBalance(date, cid);
balance = balance.setScale(2, BigDecimal.ROUND_HALF_UP);

Ну а потом просто делаем balance.compareTo(something) и всех делов.

Автор:  borisk [ 15 окт 2014, 13:06 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Alex-XXI писал(а):
Скрипт добавлен в договор, а созданный java-класс добавлен в скрипт. В клиенте биллинга на вкладке логов выполнения скриптов поведения тоже пусто.


А где была проблема, не подскажете? Просто у меня то же самое. Скрипт создан и скомпилирован, добавлен на договор, но (судя по логам) не выполняется. Правда оговорюсь - я тестирую создание периода не через "реальное" подключение клиента к сервису, а просто через создание периода "вручную". Может в этом случае событие не генерируется?

Автор:  Amir [ 15 окт 2014, 15:19 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Нет, не генерируется. Только при попытке подключения или текущей активной сессии.

Автор:  Amir [ 15 окт 2014, 15:20 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

И еще лучше сначала логи Access/Accounting смотреть.

Автор:  stark [ 15 окт 2014, 16:56 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

borisk писал(а):
Alex-XXI писал(а):
Скрипт добавлен в договор, а созданный java-класс добавлен в скрипт. В клиенте биллинга на вкладке логов выполнения скриптов поведения тоже пусто.


А где была проблема, не подскажете? Просто у меня то же самое. Скрипт создан и скомпилирован, добавлен на договор, но (судя по логам) не выполняется. Правда оговорюсь - я тестирую создание периода не через "реальное" подключение клиента к сервису, а просто через создание периода "вручную". Может в этом случае событие не генерируется?



Так этот скрипт, как раз и создает период, если его нет. А вы вручную создаете период - он не имеет к этому отношения.

Автор:  borisk [ 16 окт 2014, 01:20 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Ну просто событие называется "Запрос учетного периода". Вот я и не совсем правильно, видимо, понял. Хорошо, буду экспериментировать на реальном подключении.

Автор:  snark [ 16 окт 2014, 03:19 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

borisk писал(а):
событие называется "Запрос учетного периода"

AFAIR оно всегда, еще со времен dialup, генерировалось при 1-м реальном, физическом подключении в учетном месяце.

Автор:  borisk [ 17 окт 2014, 15:00 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Господа, конечно извиняюсь что в этой теме, но в форуме npay не отвечают. А ни кто не сталкивался с такой проблемой - скрипт делает наработку без существования реальной абонплаты на договоре. При этом на договоре могут присутствовать другие абонплаты (например за реальный IP). Соответственно если мы делаем обсчет абонплаты по данному договору, то теряем выставленную скриптом наработку. И это не есть правильно :(

Автор:  Amir [ 17 окт 2014, 15:47 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Да, при переобсчете абонплаты удаляют наработки по всем своим услугам.
Т.е. услугу желательно тогда указывать не из модуля абонплат.
Или использовать наборы услуг - при переобсчете набора услуг - удаляются наработки услуг только из набора.

Автор:  borisk [ 17 окт 2014, 17:59 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Ага, понял, спасибо. А еще не подскажете - как для 5.2 в скрипте реализовать следующую задачу: узнать наработку по абонплате X для тарифа Y в период Z. То бишь я не хочу все же жестко забивать в скрипт сумму абонплаты, а хочу чтобы он брал ее из тарифа.

Автор:  Amir [ 17 окт 2014, 19:18 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

http://wiki.bitel.ru/index.php/Определение_размера_абонентской_платы
Попробуйте
calculator.setActiveFromDate( startMonth );
calculator.setExecutingTime( endMonth );

Но если будет не внутри одного календарного месяца - не сработает.

Автор:  borisk [ 18 окт 2014, 21:08 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Спасибо! И сразу же опять вопрос - судя по вызовам Calculator он позволяет сделать обсчет сразу по нескольким договорам. Но при этом еще надо указывать набор услуг и тарифов. А нет возможности посчитать весь набор услуг по всем используемым тарифам у данных договоров? Я пробовал указывать пустой ArrayList для setContractTariff и setServiceObjectList, пробывал вообще не указывать эти параметры - не получается.

Автор:  borisk [ 18 окт 2014, 21:26 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

А нет, извиняюсь, разобрался. Он считает, просто информирует о том, что в процессе обсчета были ошибки.
А вообще - Calculator весьма полезный класс, почему же до сих пор нет его описания в документации?

Автор:  borisk [ 19 окт 2014, 12:35 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Amir писал(а):
http://wiki.bitel.ru/index.php/Определение_размера_абонентской_платы
Попробуйте
calculator.setActiveFromDate( startMonth );
calculator.setExecutingTime( endMonth );

Но если будет не внутри одного календарного месяца - не сработает.


А точно? Провел эксперимент с переходом дат через месяц. Калькулятор вернул правильный результат.

Цитата:
Сервер: вер. 5.2 сборка 1597 от 04.06.2014 19:45:26
os: Linux; java: Java HotSpot(TM) 64-Bit Server VM, v.1.6.0_43

card вер. 5.2 сборка 206 от 06.05.2014 18:45:53
enaza вер. 5.2 сборка 47 от 26.12.2012 17:59:24
gorod вер. 5.2 сборка 155 от 25.03.2013 14:32:28
inet вер. 5.2 сборка 1323 от 03.06.2014 01:18:15
mps вер. 5.2 сборка 181 от 06.12.2013 22:27:49
npay вер. 5.2 сборка 207 от 15.04.2014 11:37:49
rentsoft вер. 5.2 сборка 45 от 26.12.2012 17:59:45
reports вер. 5.2 сборка 198 от 16.05.2014 14:54:34

Автор:  borisk [ 19 окт 2014, 22:01 ]
Заголовок сообщения:  Re: [5.2]Скрипт обработки запроса учетного периода

Хотя да, вы были правы. Через месяц не считает. Но вот другая странность... вот такой вот код:
Код:
   private Map runCalculator(Setup setup, String cid, Calendar startPeriod, Calendar endPeriod) {
      Calculator   calculator = new Calculator();

      calculator.setActiveFromDate(startPeriod);
      calculator.setExecutingTime(endPeriod);
      calculator.setPreCalc();
      calculator.initTask( setup, 0, "mid=" + Constants.NPAY_MID);
      calculator.setCids( cid );
      calculator.startTask();
      
      Map map   = calculator.getCostCache().getContractAccounts();

      return map;
   }


В случает дат 2014-10-19 2014-10-31 (при тарифе месячное снятие пропорционально периоду) возвращает правильную сумму 784.19. А при 2014-11-01 2014-11-18 - возвращает полный тариф 1870.00. Почему так?

Страница 1 из 1 Часовой пояс: UTC + 5 часов [ Летнее время ]
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/