BiTel

Форум BiTel
bgbilling.ru     docs.bitel.ru     wiki.bitel.ru     dbinfo.bitel.ru     bgcrm.ru     billing.bitel.ru     bitel.ru    
Текущее время: 29 мар 2024, 00:40

Часовой пояс: UTC + 5 часов [ Летнее время ]




Начать новую тему Ответить на тему  [ 1 сообщение ] 
Автор Сообщение
СообщениеДобавлено: 16 мар 2011, 13:11 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Допустим, мы хотим знать, сколько клиенту будет стоить на его тарифе следующие x МБ или y минут.
Код ниже позволяет получить эту цифру.
Указываем mid, cid, sid, amount (в байтах или секундах) и считаем.


Внимание! Скрипт не тестировался в боевых условиях, поэтому возможны накладки.
!!! Не запускать в контексте шедулера параллельно переобсчету сессий dialup !!!
!!! Не запускать в контексте радиус-сервера !!!


На вики выкладывать пока рано.
Класс DialupPrecalculator - копипаст кусков из SessionRecalculator.

Глобальный скрипт поведения:
Код:
import bitel.billing.server.tariff.*;
import java.util.*;

import java.util.Calendar;
import java.sql.*;

import bitel.billing.server.dialup.calc.ContractData;
import bitel.billing.server.dialup.calc.ContractDataStorage;
import ru.bitel.bgbilling.server.util.ModuleSetup;
import ru.bitel.bgbilling.server.util.ServerUtils;
import ru.bitel.bgbilling.server.util.Setup;
import bitel.billing.server.MaxTrafficCalculator;
import bitel.billing.server.tariff.detail.TariffDetailUtils;
import bitel.billing.server.dialup.calc.CalcPeriod;
import bitel.billing.server.dialup.bean.DialUpSessionUtils;

public void main( setup, con, conSlave )
{
   int mid = 1;
   int sid = 2;
   int cid = 123;
   long amount = 105906176; //101 MB
   DialupPrecalculator precalculator = new DialupPrecalculator(mid, con, conSlave, setup);
   Double cost = precalculator.precalculate(Calendar.getInstance(), Calendar.getInstance(), cid, sid, amount);
   print(cost);
}

class DialupPrecalculator{
   private String sids;
   private ContractDataStorage contractDataStorage;
   private int mid = -1;
   private Calendar _date1;
   private Calendar _date2;
   private Calendar startMonth;
   private Calendar endMonth;
   private Connection con;
   private Connection conSlave;
   private ModuleSetup moduleSetup;
   private transient Setup setup;

   public DialupPrecalculator(int mid, java.sql.Connection con, java.sql.Connection conSlave, Setup setup){
      this.mid = mid;

      this.con = con;
      this.conSlave = conSlave;
      this.setup = setup;
      this.moduleSetup = this.setup.getModuleSetup(Integer.valueOf(this.mid));
      this.sids = MaxTrafficCalculator.getModuleServicesWithoutMaxTraf(this.con, this.mid, this.moduleSetup);
   }

   /**
   *   dtime - дата старта предполагаемого начисления,
   *   date2 - дата окончания начисления. Например, если мы вычисляем услугу типа "время", то date2=date1 + amount сек (не проверял)
   */
   public Double precalculate(Calendar dtime, Calendar date2, int cid, int sid, long amount){

      Double result = null;

      this._date1 = dtime;
      this._date2 = date2;

      this.startMonth = ((Calendar)this._date1.clone());
      this.startMonth.set(5, 1);

      this.endMonth = ((Calendar)this._date2.clone());
      this.endMonth.set(5, this.endMonth.getActualMaximum(5));

      this.contractDataStorage = new ContractDataStorage(this.conSlave, this.mid, this.sids, this._date1, this._date2, this.startMonth, this.endMonth);

      Set tariffDetailRangeTakeAllSet = TariffDetailUtils.getCostTypeRangeTakeAllIdSet(this.moduleSetup);

      ContractData currentContractData = this.contractDataStorage.getContractData(cid, Integer.MAX_VALUE, dtime);
      CalcPeriod period = currentContractData.getCalcPeriod(this._date1);
      TariffTreeSet.TariffSetEntry tse = currentContractData.tts.getTreeEntry(this._date1);

        if ((tse != null) && (period != null))
        {
         TariffRequest calcReq = new TariffRequest();
         calcReq.setRequestParam("cid", Integer.valueOf(cid));
         calcReq.setRequestParam("action", "calculate");
         calcReq.setRequestParam("month_time", this.startMonth);
         
         float servicePart = DialUpSessionUtils.getPart(period.start, period.end, sid, currentContractData.serviceRanges);
         float tariffPart = tse.getPartOnPeriod(period.start, period.end);
         float tariffPartSuspended = tse.getPartOnPeriod(period.start, period.end, currentContractData.suspendedPeriods);
         
         calcReq.setRequestParam("sid", Integer.valueOf(sid));
         calcReq.setRequestParam("time", dtime);
         calcReq.setRequestParam("amount", Long.valueOf(amount));
         calcReq.setRequestParam("period_end", period.end);
         calcReq.setRequestParam("part_service", Float.valueOf(servicePart));
         calcReq.setRequestParam("part_tariff", Float.valueOf(tariffPart));
         calcReq.setRequestParam("part_tariff_suspended", Float.valueOf(tariffPartSuspended));
         calcReq.setRequestParam("tariffOptions", currentContractData.tariffOptions);
         calcReq.setRequestParam("costTypeRangeTakeAllSet", tariffDetailRangeTakeAllSet);
         
         tse.getTree().processRequest(calcReq);
         
         Float costAmount = (Float)calcReq.getResponseParam("costAmount");
         Float dividend = (Float)calcReq.getResponseParam("cost");
         Long divisor = (Long)calcReq.getResponseParam("divisor");
         
         if (calcReq.wasAccepted())
         {
            Double cost = null;
         
            if (costAmount != null)
            {
               cost = Double.valueOf(costAmount.doubleValue());
            }
            else if ((dividend != null) && (divisor != null) && (divisor.longValue() > 0L))
            {
               cost = Double.valueOf(amount * dividend.doubleValue() / divisor.longValue());
            }
            result = cost;
         }
         
         //Непонятно почему, но после вычисления нужно делать reset для корректного обсчета в следующий раз. Хотя в начале в getContractData делается тот же reset.
         //Вместо этого в SessionRecalculator тут делается init
         TariffRequest req = new TariffRequest();
         req.setRequestParam("cid", Integer.valueOf(cid));
         req.setRequestParam("action", "reset");
         
         tse.getTree().processRequest(req);
        }
      return result;
   }
}


Ушло 2 дня.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ 1 сообщение ] 

Часовой пояс: UTC + 5 часов [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
POWERED_BY
Русская поддержка phpBB
[ Time : 0.060s | 20 Queries | GZIP : On ]