Скрипт глобальный отмены перехода на тарифы при неоплате

Материал из BiTel WiKi

Версия от 12:47, 9 февраля 2010; DimOn (Обсуждение | вклад)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Условие перевода на данный тариф - наличие полной оплаты за предыдущий месяц. К примеру выставлен новый тариф с 01.11.09, значит надо 1 ноября проверить баланс: исходящее сальдо на конец октября должно быть (по модулю) меньше или равно сумме наработки и расхода за октябрь. Если это условие не выполняется, то перевод на новый тариф аннулируется. Желательно с сохранением истории.

Исходящий остаток ноября если брать, то он будет включать наработку и расход ноября, обязятельства по оплате которых наступают только в конце декабря. Нам нужно, чтобы октябрь был оплачен полностью.

ноябрь 2009 Входящий остаток на начало месяца -11617.05 ноябрь 2009 Приход за месяц 11617.05 ноябрь 2009 Наработка за месяц 11005.54 ноябрь 2009 Расход за месяц 0.00 ноябрь 2009 Исходящий остаток на конец месяца -11005.54

сальдо на 1 ноября + платежи ноября= -11617,05+11617,05=0

import bitel.billing.server.util.*;
import bitel.billing.server.contract.bean.*;
import java.sql.*;
import java.math.*;
 
import bitel.billing.server.admin.eventbus.*;
import bitel.billing.server.admin.eventbus.event.*;
 
/** если стоит флаг, то работа в тестовом режиме - только пишется что сделано, но по факту не делается - не удаляется дата платежа, не удаляется тариф и т.п.*/
final static boolean IS_TEST = true;
/** комментарий, который прибавляется к предыдущему тарифу, в случае отмены перехода на новый */
final static String CANCEL_COMMENT = "Отмена перевода на тариф \"%s\", невыполнение условий тарифа.";
/** список id тарифов, на которые действует скрипт. в кавычках, через запятую */
final static String TARIFFS = "25,1,2";
 
public void main( setup, con, conSlave )
{
	print( "запуск скрипта..." );
	BalanceUtils balanceManager = new BalanceUtils( con );
	ContractTariffManager contractTariffManager = new ContractTariffManager( con );
	// вычисляем даты	, начало месяца и предыдущий день
	Calendar curMonthBegin = new GregorianCalendar();
	curMonthBegin.set( Calendar.DATE, curMonthBegin.getActualMinimum( Calendar.DATE ) );
	Calendar prevMonthEnd = curMonthBegin.clone();
	prevMonthEnd.add( Calendar.DATE, -1 );
	print( "текущее начало месяца: " + TimeUtils.formatDate( curMonthBegin ) + ", конец предыдущего месяца: " + TimeUtils.formatDate( prevMonthEnd ) );
	// делаем запрос всех договоров, у которых сегодня начинается новый тариф
	String query = "SELECT `contract_tariff`.*, `contract`.`title` as contract_title, `tariff_plan`.`title` as tariff_plan_title "+
					"FROM `contract_tariff` "+
					"LEFT JOIN `contract` ON `contract`.`id`=`contract_tariff`.`cid` "+
					"LEFT JOIN `tariff_plan` ON `tariff_plan`.`id`=`contract_tariff`.`tpid` "+
					"WHERE `contract_tariff`.`date1`=? AND `tariff_plan`.`id` in ("+TARIFFS+")";
	PreparedStatement ps = con.prepareStatement( query );
	ps.setDate( 1, TimeUtils.convertDateToSqlDate( curMonthBegin.getTime() ) );	
	ResultSet rs = ps.executeQuery();
	while( rs.next() )
	{
		// получаем данные о конкретном догогоре
		int id=rs.getInt("id");
		int cid=rs.getInt("cid");
		String contractTitle=rs.getString("contract_title");
		String comment=rs.getString("comment");
		String tariffTitle=rs.getString("tariff_plan_title");
		print("=> договор '"+contractTitle+"' хочет " + TimeUtils.formatDate( curMonthBegin ) + " изменить тариф на '"+tariffTitle+"' (комментарий тарифа договора: '"+comment+"')");
 
		// ищем "предыдущий" тариф, тот у которого вчера закончился срок
		int id_prev=-1;
		String query2 = "SELECT `contract_tariff`.*, `tariff_plan`.`title` as tariff_plan_title "+
						"FROM `contract_tariff` "+						
						"LEFT JOIN `tariff_plan` ON `tariff_plan`.`id`=`contract_tariff`.`tpid` "+
						"WHERE `contract_tariff`.`date2`=? AND `contract_tariff`.`cid`=?";
		PreparedStatement ps2 = con.prepareStatement( query2 );
		ps2.setDate( 1, TimeUtils.convertDateToSqlDate( prevMonthEnd.getTime() ) );	
		ps2.setInt( 2, cid );	
		ResultSet rs2 = ps2.executeQuery();
		if( rs2.next() )
		{
			id_prev=rs2.getInt("id");
			print( "найден предыдуший тариф - '"+rs2.getString("tariff_plan_title")+"', заканчивающийся "+TimeUtils.formatDate( prevMonthEnd )+"." );
		}
		else
		{
			print( "внимание! не найдено предыдущего тарифа, заканчивающегося "+TimeUtils.formatDate( prevMonthEnd )+". Ничего не будем делать." );
			continue;
		}
		// если есть ещё один такой же - пишем, что произошёл казус
		if( rs2.next() )
		{
			print( "внимание! существует как минимум ещё один тариф - '"+rs2.getString("tariff_plan_title")+"', заканчивающийся "+TimeUtils.formatDate( prevMonthEnd )+". ничего не будем делать." );
			continue;
		}
		rs2.close();
		ps2.close();
 
		// проверяем условие для смены тарифа
		BigDecimal summa1 = balanceManager.getBalanceSumma1( prevMonthEnd.getTime(), cid );
		print( "входящий остаток : " + summa1.toPlainString() );
		BigDecimal saldo = balanceManager.getSaldo( prevMonthEnd.getTime(), cid );
		print( "входящий остаток + приход : " + saldo.toPlainString() );
		// если условие выполняется - ничего не делаем
		if( saldo.compareTo( BigDecimal.ZERO ) >= 0 ) //TODO
		{
			print( "условие выполняется, ничего не делаем." );
		}
		// иначе - отменяем
		else
		{
			print( "внимание! условие не выполняется, отменяем переход." );
			// удаляем тариф	
			print( "удаляем новый тариф '"+tariffTitle+"' из contract_tariff{id='"+id+"'}..." );
			if( !IS_TEST )
			{
				contractTariffManager.deleteContractTariff( id );
			}
			// правим предыдущий
			print( "правим предыдущий тариф из contract_tariff{id='"+id_prev+"'}..." );
			ContractTariff contractTariff = contractTariffManager.getContractTariffByID( id_prev );
        	contractTariff.setDate2( null );
        	contractTariff.setComment( contractTariff.getComment()+CANCEL_COMMENT.replaceAll("%s",tariffTitle) );
			if( !IS_TEST )
			{
				contractTariffManager.updateContractTariff( contractTariff );
			}
			// на всякий случай
			BillingEventBus.publish( new TariffChangedEvent( cid ) );
		}
	}
	rs.close();
	ps.close();
}

сделано для 4.6, вешается на глобальный, запускается в начале месяца.

--dimOn 08:48, 10 декабря 2009 (UTC)

Личные инструменты