BiTel

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

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




Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
СообщениеДобавлено: 27 сен 2017, 11:54 
Не в сети

Зарегистрирован: 15 июл 2015, 12:21
Сообщения: 48
Карма: 5
Добрый день.
Есть связка супердоговора и субдоговора с зависимым балансом.
На супердоговор приходят платежи, на субдоговоре начисляется наработка.
На субдоговоре включена возможность временного понижения лимита пользователем.
При приходе платежа на супердоговор на субдоговоре этого не видно, и временное понижение лимита всегда помечается как просроченное. Как это победить?

Версия биллинга 7.0


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 27 сен 2017, 12:09 
Не в сети
Разработчик

Зарегистрирован: 07 апр 2007, 23:51
Сообщения: 4489
Откуда: Уфа, Россия
Карма: 186
В таком режиме не будет работать, в данном случае управление лимитом надо делать на супердоговлре


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 04 май 2018, 11:16 
Не в сети

Зарегистрирован: 15 июл 2015, 12:21
Сообщения: 48
Карма: 5
Скрипт для решения этой задачи. На основе ru.bitel.bgbilling.kernel.contract.limit.server.bean.LimitManager (fernflower). Работает 4 месяца. Может, кому пригодится.
Код:
package ru.XXX.bgbilling.kernel.contract.dyn;

import java.sql.Connection;

import bitel.billing.server.contract.bean.Contract;
import bitel.billing.server.contract.bean.ContractManager;
import ru.bitel.bgbilling.kernel.contract.balance.server.event.PaymentEvent;
import ru.bitel.bgbilling.kernel.script.server.dev.EventScriptBase;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.sql.ConnectionSet;

import ru.XXX.bgbilling.lib.CustomLimitManager;

   /**
    * По событию прихода платежа на супердоговор
    * восстанавливает временные понижения лимитов
    * на всех зависимых дебетовых субдоговорах.
    * @param connnection
    * @param event - событие о приходе платежа для супердоговора
    * @throws BGException
    *
    */
   
public class RestoreSubcontractsLimits
   extends EventScriptBase<PaymentEvent>
{
   @Override
   public void onEvent( PaymentEvent event, Setup setup, ConnectionSet set )
      throws Exception
   {
//      if (event.getContractId() != 17738) // 888888 for test
//         return;
      
      Connection con = set.getConnection();
      try (ContractManager cm = new ContractManager(con)) {
         Contract contract = cm.getContractById(event.getContractId());
         if (contract.isSuper() && contract.getBalanceMode() == Contract.DEBET_BALANCE_MODE) {
            CustomLimitManager clm = new CustomLimitManager(con, event);
            clm.clientPaymentAllSubcontracts();
         }
      }
   }

}



Код:
package ru.XXX.bgbilling.lib;

import java.math.BigDecimal;
import java.sql.*;

import ru.bitel.common.TimeUtils;
import bitel.billing.server.contract.bean.*;
import ru.bitel.bgbilling.common.BGException;
import ru.bitel.bgbilling.kernel.contract.balance.common.bean.Payment;
import ru.bitel.bgbilling.kernel.contract.balance.server.bean.PaymentDao;
import ru.bitel.bgbilling.kernel.contract.balance.server.event.PaymentEvent;
import ru.bitel.bgbilling.kernel.contract.limit.common.bean.ContractLimitLog;
import ru.bitel.bgbilling.kernel.contract.limit.server.bean.ContractLimitLogManager;
import ru.bitel.bgbilling.kernel.contract.limit.server.bean.LimitManager;
import ru.bitel.bgbilling.kernel.module.common.bean.User;

import org.apache.log4j.Logger;


public final class CustomLimitManager
{
   public static final int SUB_MODE_DEPEND_BALANCE = 0;
   

   public CustomLimitManager(Connection connection, PaymentEvent event){
      this.connection = connection;
      this.event = event;
   }
   
   private final Connection connection;
   private final PaymentEvent event;
   private Contract subcontract;
   private Contract supercontract;
   private int currentLimitStatus;
   private int loweringLimitId;
   private String existingPayments;
   private BigDecimal sum;
   private BigDecimal unpaidLimitSumm;
   
   private final static Logger logger = Logger.getLogger( CustomLimitManager.class);
   
   public void clientPaymentAllSubcontracts() throws BGException
   {
      synchronized (LimitManager.limitMutex) {
         
         BigDecimal rest = event.getPayment().getSum();

         try( ContractManager cm = new ContractManager( connection);
               PaymentDao paymentDao = new PaymentDao( connection);
            )
         {
            supercontract = cm.getContractById(event.getContractId());
            
            pays:
            for (Contract subcon : cm.getSubContracts(event.getContractId(), SUB_MODE_DEPEND_BALANCE)) {
               this.subcontract = subcon;
               
               if( subcontract == null)
                  continue;
               
               if (subcontract.getBalanceMode() != Contract.DEBET_BALANCE_MODE) {
                  logger.warn(String.format("Subcontract %s is not in debet balance mode. Skip.", subcontract.getTitle()));
                  continue;
               }
         
               try(ResultSet unpayedLimitRs = getUnpayedLimitRs()){
                  for (boolean isPayIdSaved = false; unpayedLimitRs.next(); rest = sum.subtract(unpaidLimitSumm)) {
                     currentLimitStatus = unpayedLimitRs.getInt("status");
                     loweringLimitId = unpayedLimitRs.getInt("id");
                     existingPayments = unpayedLimitRs.getString("pids");
                     unpaidLimitSumm = unpayedLimitRs.getBigDecimal("summ");
                     sum = rest.add(unpayedLimitRs.getBigDecimal("rest"));
                     sum = sum.add( getPreviousPaymentsSum(paymentDao));
                     
                     if (!isPayIdSaved) {
                        savePaymentId();
                        isPayIdSaved = true;
                     } else {
                        saveMoneyRest( rest);
                     }
         
                     if (notEnoughMoney()) {
                        if (noMoneyAtAll())
                           setContractLimitStatus( LimitManager.VPAY_NOT_PAYOFFED);
                        else
                           setContractLimitStatus( LimitManager.VPAY_PARTIAL_PAYOFFED);
                        
                        break pays;
                     }
                     else {
                        setContractLimitStatus(LimitManager.VPAY_PAYOFFED);
                        restoreSubcontractLimit(unpayedLimitRs.getInt("clp_id"), unpaidLimitSumm.negate());
                     }
                  }
               }
               catch (SQLException e) {
                  throw new BGException(e);
               }
            }
         }
      }
   }

   private void setContractLimitStatus( int newStatus)
   throws SQLException
   {
      if (currentLimitStatus != newStatus) {
         if( newStatus == LimitManager.VPAY_PAYOFFED){
            String updQuery = "UPDATE contract_limit_manage SET status=?, date2=? WHERE id=?";
            try (PreparedStatement ps = connection.prepareStatement(updQuery)) {
               ps.setInt(1, newStatus);
               ps.setDate(2, TimeUtils.convertDateToSqlDate(event.getPayment().getDate()));
               ps.setInt(3, loweringLimitId);
               ps.executeUpdate();
               logger.info(String.format("subcontract: %s. Limit: %s (Id: %d) payoffed",
                  subcontract.getTitle(), unpaidLimitSumm.negate().toPlainString(), loweringLimitId));
            }
         }
         else{
            String updQuery = "UPDATE contract_limit_manage SET status=? WHERE id=?";
            try (PreparedStatement ps = connection.prepareStatement( updQuery)) {
               ps.setInt(1, newStatus);
               ps.setInt(2, loweringLimitId);
               ps.executeUpdate();
               logger.info(String.format("subcontract: %s. Limit: %s (Id: %d) NOT payoffed",
                  subcontract.getTitle(), unpaidLimitSumm.negate().toPlainString(), loweringLimitId));
            }
         }
      }
   }
   
   private void restoreSubcontractLimit(int restoreLimitTaskId, BigDecimal unpaidLimitSum) {
   //   synchronized (LimitManager.limitMutex) {
         try{
            if (wasUnpayedLimit()) {
               String paysIds = getPaysIds(restoreLimitTaskId);
               deleteLimitRecoveryTask(restoreLimitTaskId);
               recalcLimitSum(unpaidLimitSum);
               subcontractLimitRecoveryLogging(paysIds, unpaidLimitSum);
            }
         } catch (Exception e) {
            e.printStackTrace();
         }
   //   }
   }

   private boolean notEnoughMoney(){
      return sum.compareTo(unpaidLimitSumm) < 0;
   }
   
   private boolean noMoneyAtAll(){
      return sum.compareTo(BigDecimal.ZERO) <= 0;
   }
   
   private void saveMoneyRest( BigDecimal rest)
   throws SQLException
   {
      try (PreparedStatement ps = connection.prepareStatement("UPDATE contract_limit_manage SET rest=? WHERE id=?")) {
         ps.setBigDecimal(1, rest);
         ps.setInt(2, loweringLimitId);
         ps.executeUpdate();
      }
      
   }
   
   private void savePaymentId()
   throws SQLException
   {
      try (PreparedStatement ps = connection.prepareStatement("UPDATE contract_limit_manage SET pids=? WHERE id=?")) {
         ps.setString(1, existingPayments == null ? "" + event.getPayment().getId()
               : existingPayments + "," + event.getPayment().getId());
         ps.setInt(2, loweringLimitId);
         ps.executeUpdate();
      }
      
   }
   
   private BigDecimal getPreviousPaymentsSum( PaymentDao pmDao)
   throws BGException
   {
      BigDecimal sum = BigDecimal.ZERO;
      for (Payment payment : pmDao.getPaymentsById(existingPayments)) {
         if (payment != null) {
            sum = sum.add(payment.getSum());
         }
      }
      return sum;   
   }
   
   private ResultSet getUnpayedLimitRs()
   throws SQLException
   {
      PreparedStatement ps1 = connection.prepareStatement("SELECT * FROM contract_limit_manage WHERE cid=? AND status<?");
      ps1.setInt(1, subcontract.getId());
      ps1.setInt(2, LimitManager.VPAY_PAYOFFED);
      return ps1.executeQuery();
   }

   private String getPaysIds(int taskId)
         throws SQLException {
      try( PreparedStatement psSelPids = connection.prepareStatement(
               "SELECT pids FROM contract_limit_manage WHERE clp_id = ?");
         )
      {
         psSelPids.setInt(1, taskId);
         ResultSet rs1 = psSelPids.executeQuery();
         if( rs1.next())
            return rs1.getString("pids");
         else
            return "?";
      }
   }
   
   private void deleteLimitRecoveryTask( int taskId)
         throws SQLException
   {
      try(PreparedStatement psDeletePeriodLimit = connection.prepareStatement(
            "DELETE FROM contract_limit_period WHERE id = ?");
            
         PreparedStatement psUpdateLimitManage = connection.prepareStatement(
            "UPDATE contract_limit_manage SET clp_id = NULL  WHERE clp_id = ?");
         )
      {
         psDeletePeriodLimit.setInt(1, taskId);  // удаляем задание возвращения лимита
         psDeletePeriodLimit.executeUpdate();
         
         psUpdateLimitManage.setInt(1, taskId);  // удаляем ссылку на задание возвращения лимита
         psUpdateLimitManage.executeUpdate();
      }
   }
   
   private void recalcLimitSum( BigDecimal unpaidLimitSumm)
         throws SQLException{
      try(PreparedStatement psUpdateLimit = connection.prepareStatement(
            "UPDATE contract SET closesumma = closesumma - ? WHERE id = ?");
         )
      {
         psUpdateLimit.setBigDecimal(1, unpaidLimitSumm); // уменьшаем лимит на сумму обещ. платеа
         psUpdateLimit.setInt(2, subcontract.getId());
         psUpdateLimit.executeUpdate();
      }
   }
   
   private boolean wasUnpayedLimit(){
      return unpaidLimitSumm.compareTo( BigDecimal.ZERO) != 0;
   }
   
   private void subcontractLimitRecoveryLogging(String pays, BigDecimal limitValue)
         throws BGException{
      try(ContractLimitLogManager contractLimitLogManager = new ContractLimitLogManager(connection);)
      {
         ContractLimitLog contractLimitLog = new ContractLimitLog();
         contractLimitLog.setUserId(User.USER_SERVER);
         contractLimitLog.setLimitValue(subcontract.getBalanceLimit());
         contractLimitLog.setContractId(subcontract.getId());
         contractLimitLog.setComment(String.format("Восст. лим. на %s (платеж: %s на договор: %s)",
               limitValue.negate().toPlainString(), pays, supercontract.getTitle()));
         
         contractLimitLogManager.addContractLimitLog(contractLimitLog);
      }
   }
}



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

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


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

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


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

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