Скрипт стандартной логики перетирания статусов

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

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

Это скрипт поведения, реализующий стандартную логику перетирания статусов для события "задание логики перетирания статусов".

Для версии 5.1/5.2

import bitel.billing.server.util.*;
import java.sql.*;
import bitel.billing.server.contract.bean.*;
import bitel.billing.server.script.bean.event.*;
import bitel.billing.server.contract.bean.ContractStatusManager.ContractStatusManager4Script;
 
public void onEvent( event1, setup, con, conSlave )
{
	ContractSetStatusLogicEvent event = (ContractSetStatusLogicEvent)event1;
	print( "do change status!" );
 
	// старый статус
	ContractStatus status = event.getStatus1();
	// Приходящий статус
	ContractStatus newStatus = event.getStatus2();
	// Самый что ни на есть оригинальный статус
	ContractStatus originalStatus = event.getOriginalStatus();
 
	// юзер ид
	Integer userId = event.getUserId();
 
	// менеджер ContractStatusManager, оптимизированный для этого скрипта
	ContractStatusManager4Script csm = new ContractStatusManager4Script( con );
 
	// здесь мы вычисляем предыдущие и следующие дни от оригинального статуса.
	// на самом деле в оригинальном алгоритме это делается ДО всего этого цикла, потому,
	// что оригинальный статус не меняется. здесь же мы можем сменить границы промежутка
	// так что если мы меняем newStatus дальше, то тут каждый раз надо брать следующий
	// и предыдущий от newStatus(!), а не как здесь от originalStatus
	Calendar prevDay = new GregorianCalendar();
	prevDay.setTime( originalStatus.getDateFrom() );
	prevDay.add( Calendar.DAY_OF_MONTH, -1 );
 
        // следующий день после конца нового статуса (или null)
	Calendar nextDay = null;
	if( originalStatus.getDateTo() != null )
	{
		nextDay = new GregorianCalendar();
		nextDay.setTime( originalStatus.getDateTo() );
		nextDay.add( Calendar.DAY_OF_YEAR, 1 );
	}
 
	// далее - полный агалог стандартного алгоримта.
            // статусы не конфликтуют
    		// not:
        	// old .......[*****!.....?
        	// new ..........!*****]..?
        	// not:
        	// old ..........!*****]..?
        	// new .......[*****!.....?
            if( !(newStatus.getDateFrom() == null || status.getDateTo() == null || TimeUtils.dateBeforeOrEq( newStatus.getDateFrom(), status.getDateTo() ) ) ||
                !(newStatus.getDateTo() == null || status.getDateFrom() == null || TimeUtils.dateBeforeOrEq( status.getDateFrom(), newStatus.getDateTo() ) ) )
            {
            	// ничего не делаем, просто уходим к следующему статусу
            	event.setProcessed( true );
				return;
            }
 
 
            // полное перекрытие статуса
            // old .......!*****?.....
        	// new ......!************
            //
            // old .......!*****!.....
        	// new .....!*********!...
            if( TimeUtils.dateBeforeOrEq( newStatus.getDateFrom(), status.getDateFrom() ) &&
                (newStatus.getDateTo() == null || (status.getDateTo() != null && TimeUtils.dateBeforeOrEq( status.getDateTo(), newStatus.getDateTo() ) ) ) )
            {
            	// перетираем (старый удаляем)
            	csm.deleteStatus( status.getId() );
            }
            else
            {
                // разрыв статусом старого статуса
                // old .....[*****].....
            	// new ......[**!.......
            	// ...
                if( newStatus.getDateTo() != null && TimeUtils.periodInRange( newStatus.getDateFrom(), newStatus.getDateTo(), status.getDateFrom(), status.getDateTo() ) )
                {
                	// разрываем
                	ContractStatus nextStatus = status.clone();
                	nextStatus.setDateFrom( nextDay.getTime() );
 
                	if( nextStatus.getDateTo() == null || TimeUtils.dateBeforeOrEq( nextStatus.getDateFrom(), nextStatus.getDateTo() ) )
                	{
                		csm.updateStatus( nextStatus, userId );
                	}
 
                	status.setDateTo( prevDay.getTime() );
                	csm.doByPeriod( status, userId );
                }
                // перекрытие старого статуса "слева"
                // old ........!*****]..
            	// new .....?******!....
                else if ( newStatus.getDateTo() != null && TimeUtils.dateInRange( status.getDateFrom(), newStatus.getDateFrom(), newStatus.getDateTo() ) )
                {
                	// двигаем старый до следующего дня после нового
                    // old .............!]..
                	// new .....?******!....
                	status.setDateFrom( nextDay.getTime() );
                	csm.doByPeriod( status, userId );
                }
                // перекрытие старого статуса "справа"
                // old ....[*****]......
            	// new ......[******]...
                else if ( status.getDateTo() == null || TimeUtils.dateInRange( status.getDateTo(), newStatus.getDateFrom(), newStatus.getDateTo() ) )
                {
                	// двигаем старый до предыдущего дня до нового
                    // old ....[]...........
                	// new ......[******]...
                	status.setDateTo( prevDay.getTime() );
                	csm.doByPeriod( status, userId );
                }
            }
 
	// чтобы не вызвалась стандартная логика
	event.setProcessed( true );
}

--dimOn 06:29, 13 октября 2010 (UTC)

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