forum.bitel.ru http://forum.bitel.ru/ |
|
Приход платежа после понижения лимита в субдоговоре http://forum.bitel.ru/viewtopic.php?f=22&t=12644 |
Страница 1 из 1 |
Автор: | arj57 [ 27 сен 2017, 11:54 ] |
Заголовок сообщения: | Приход платежа после понижения лимита в субдоговоре |
Добрый день. Есть связка супердоговора и субдоговора с зависимым балансом. На супердоговор приходят платежи, на субдоговоре начисляется наработка. На субдоговоре включена возможность временного понижения лимита пользователем. При приходе платежа на супердоговор на субдоговоре этого не видно, и временное понижение лимита всегда помечается как просроченное. Как это победить? Версия биллинга 7.0 |
Автор: | skn [ 27 сен 2017, 12:09 ] |
Заголовок сообщения: | Re: Приход платежа после понижения лимита в субдоговоре |
В таком режиме не будет работать, в данном случае управление лимитом надо делать на супердоговлре |
Автор: | arj57 [ 04 май 2018, 11:16 ] |
Заголовок сообщения: | Re: Приход платежа после понижения лимита в субдоговоре |
Скрипт для решения этой задачи. На основе 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); } } } |
Страница 1 из 1 | Часовой пояс: UTC + 5 часов [ Летнее время ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |