Обработка событий процесса согласования

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

Перейти к: навигация, поиск

Класс скрипта указывается в типе процесса. Скрипт можно дополнить обработкой других событий процесса.

При изменении статуса:

  1. Оповещает с помощью вспомогательного класса Notificator создателя процесса о переключении его статуса.

Перед закрытием процесса:

  1. Проверяет, что в списковом параметре PARAMETER_SOGL_LIST проставлены все исполнители с процесса группой USER_GROUP_SOGL_DPT. Списковый параметр должен быть привязан к таблице user.

При закрытии процесса:

  1. Заполняет текстовый параметр PROCESS_PARAM_REAL_EXECUTE_TIME временем выполнения процесса.


package ru.bgcrm.dyn.ufanet.sogl;
 
import java.sql.Connection;
import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
 
import ru.bgcrm.cache.ProcessTypeCache;
import ru.bgcrm.dao.ParamValueDAO;
import ru.bgcrm.dao.process.StatusChangeDAO;
import ru.bgcrm.dyn.ufanet.Notificator;
import ru.bgcrm.dyn.ufanet.Notificator.NotificationType;
import ru.bgcrm.dyn.ufanet.Thesaurus;
import ru.bgcrm.event.Event;
import ru.bgcrm.event.ParamChangingEvent;
import ru.bgcrm.event.listener.DynamicEventListener;
import ru.bgcrm.event.process.ProcessChangedEvent;
import ru.bgcrm.event.process.ProcessChangingEvent;
import ru.bgcrm.model.BGException;
import ru.bgcrm.model.param.ParameterAddressValue;
import ru.bgcrm.model.process.Process;
import ru.bgcrm.model.process.ProcessExecutor;
import ru.bgcrm.model.process.ProcessType;
import ru.bgcrm.model.process.StatusChange;
import ru.bgcrm.util.sql.ConnectionSet;
 
public class SoglasEventProcessor
	extends DynamicEventListener
{
	private static final int PROCESS_ACCEPT_STATUS_ID = 46;
	private static final int PARAMETER_SOGL_LIST = 701;
	private static final int USER_GROUP_SOGL_DPT = 60;
	private static final int PROCESS_STATUS_AGREED = 17;
	private static final int PROCESS_PARAM_REAL_EXECUTE_TIME = 804;
 
	private static final Logger log = Logger.getLogger( SoglasEventProcessor.class );
	private Connection con;
 
	@Override
	public void notify( Event e, ConnectionSet connectionSet )
		throws BGException
	{
		con = connectionSet.getConnection();
 
		if( e instanceof ParamChangingEvent )
		{
			onParameterChanging( e );
		}
 
		else if( e instanceof ProcessChangingEvent )
		{
			onProcessChanging( (ProcessChangingEvent)e );
		}
 
		else if( e instanceof ProcessChangedEvent )
		{
			onProcessChanged( (ProcessChangedEvent)e );
		}
	}
 
	private void onProcessChanged( ProcessChangedEvent event )
		throws BGException
	{
		int statusId = event.getProcess().getStatusId();
		Process process = event.getProcess();
		ProcessType type = ProcessTypeCache.getProcessType( process.getTypeId() );
 
		int processId = process.getId();
 
		if( event.isStatus() )
		{
			ParamValueDAO paramValueDAO = new ParamValueDAO( con );
			ParameterAddressValue address = paramValueDAO.getParamAddress( process.getId(), Thesaurus.Process.PROCESS_PARAMETER_ADDRESS_ID, 1 );
 
			if( address != null )
			{
 
				String title = "Изменение статуса процесса " + process.getId();
				String text = " Статус процесса  " + process.getId() + " по адресу " + address.getValue() + " изменился на " + process.getStatusTitle();
 
				Notificator.notificate( new HashSet<Integer>( Arrays.asList( process.getCreateUserId() ) ), title, text, new HashSet<NotificationType>( Arrays.asList( NotificationType.SMS, NotificationType.NEWS, NotificationType.EMAIL ) ) );
			}
		}
 
		if( event.isStatus() && type.getProperties().getCloseStatusIds().contains( statusId ) )
		{
			StatusChangeDAO statusChangeDAO = new StatusChangeDAO( con );
 
			List<StatusChange> statusHistory = statusChangeDAO.getProcessStatus( processId, PROCESS_ACCEPT_STATUS_ID );
			if( statusHistory.isEmpty() )
			{
				return;
			}
 
			//вычисление времени решения процесса
			long diffInMillis = process.getCloseTime().getTime() - statusHistory.iterator().next().getDate().getTime();
			int diffInDays = (int)diffInMillis / 1000 / 86400;
			int diffInHours = (int)(diffInMillis / 1000 - 86400 * diffInDays) / 3600;
			int diffInMins = (int)(diffInMillis / 1000 - 86400 * diffInDays - 3600 * diffInHours) / 60;
 
			GregorianCalendar cal = new GregorianCalendar( 0, 0, diffInDays, diffInHours, diffInMins, 0 );
 
			String diffTime = String.format( "%d д. %tH:%tM", diffInDays, cal, cal );
 
			new ParamValueDAO( con ).updateParamText( processId, PROCESS_PARAM_REAL_EXECUTE_TIME, diffTime );
		}
	}
 
	private void onProcessChanging( ProcessChangingEvent event )
		throws BGException
	{
		Process process = event.getProcess();
		int processId = process.getId();
 
		if( !event.isStatus() )
		{
			return;
		}
 
		int statusId = event.getStatusChange().getStatusId();
		if( statusId != PROCESS_STATUS_AGREED )
		{
			return;
		}
 
		Set<Integer> soglSet = new ParamValueDAO( con ).getParamList( processId, PARAMETER_SOGL_LIST );
 
		for( ProcessExecutor executor : process.getProcessExecutors() )
		{
			if( executor.getGroupId() == USER_GROUP_SOGL_DPT && !soglSet.contains( executor.getUserId() ) )
			{
				throw new BGException( "Процесс должен быть согласован всеми согласователями из списка исполнителей перед закрытием" );
			}
		}
	}
 
	private void onParameterChanging( Event e )
		throws BGException
	{
		ParamChangingEvent event = (ParamChangingEvent)e;
 
		if( event.getParameter() == null || event.getParameter().getId() != PARAMETER_SOGL_LIST )
		{
			return;
		}
 
		Set<Integer> newSet = null;
 
		try
		{
			newSet = (Set<Integer>)event.getValue();
		}
		catch( Exception ex )
		{
			log.debug( ex );
		}
 
		if( newSet == null )
		{
			return;
		}
 
		checkPermission( event.getUser().getId(), new ParamValueDAO( con ).getParamList( event.getObjectId(), PARAMETER_SOGL_LIST ), newSet );
	}
 
	private void checkPermission( int userId, Set<Integer> source, Set<Integer> newSet )
		throws BGException
	{
		List<Integer> disjSet = (List<Integer>)CollectionUtils.disjunction( source, newSet );
 
		if( disjSet.size() > 1 || (disjSet.size() == 1 && !disjSet.contains( userId )) )
		{
			throw new BGException( "Вы можете проставить согласование только от своего имени" );
		}
	}
}
Личные инструменты