⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 workflowprocessor.java

📁 大家共享愉快, 共享愉快, 共享愉快, 共享愉快,共享愉快
💻 JAVA
字号:
/******************************************************************************
 * The contents of this file are subject to the   Compiere License  Version 1.1
 * ("License"); You may not use this file except in compliance with the License
 * You may obtain a copy of the License at http://www.compiere.org/license.html
 * Software distributed under the License is distributed on an  "AS IS"  basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * The Original Code is Compiere ERP & CRM Smart Business Solution. The Initial
 * Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke
 * are Copyright (C) 1999-2005 Jorg Janke.
 * All parts are Copyright (C) 1999-2005 ComPiere, Inc.  All Rights Reserved.
 * Contributor(s): ______________________________________.
 *****************************************************************************/
package org.compiere.server;

import java.sql.*;
import java.util.*;
import java.io.*;

import java.util.logging.*;
import org.compiere.util.*;
import org.compiere.wf.*;
import org.compiere.model.*;
import org.compiere.process.*;


/**
 *	Workflow Processor
 *	
 *  @author Jorg Janke
 *  @version $Id: WorkflowProcessor.java,v 1.10 2005/11/12 23:00:29 jjanke Exp $
 */
public class WorkflowProcessor extends CompiereServer
{
	/**
	 * 	WorkflowProcessor
	 *	@param model model
	 */
	public WorkflowProcessor (MWorkflowProcessor model)
	{
		super (model, 120);		//	2 minute dalay
		m_model = model;
		m_client = MClient.get(model.getCtx(), model.getAD_Client_ID());
	}	//	WorkflowProcessor
	
	/**	The Concrete Model			*/
	private	MWorkflowProcessor	m_model = null;
	/**	Last Summary				*/
	private StringBuffer 		m_summary = new StringBuffer();
	/** Client onfo					*/
	private MClient 			m_client = null;
	
	/**
	 * 	Work
	 */
	protected void doWork ()
	{
		m_summary = new StringBuffer();
		//
		wakeup();
		dynamicPriority();
		sendAlerts();
		//
		int no = m_model.deleteLog();
		m_summary.append("Logs deleted=").append(no);
		//
		MWorkflowProcessorLog pLog = new MWorkflowProcessorLog(m_model, m_summary.toString());
		pLog.setReference("#" + String.valueOf(p_runCount) 
			+ " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
		pLog.save();
	}	//	doWork

	/**
	 * 	Continue Workflow After Sleep
	 */
	private void wakeup()
	{
		String sql = "SELECT * "
			+ "FROM AD_WF_Activity a "
			+ "WHERE Processed='N' AND WFState='OS'"	//	suspended
			+ " AND EndWaitTime > SysDate"
			+ " AND AD_Client_ID=?"
			+ " AND EXISTS (SELECT * FROM AD_Workflow wf "
				+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
				+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID"
				+ " AND wfn.Action='Z'"		//	sleeping
				+ " AND wf.AD_WorkflowProcessor_ID IS NULL OR wf.AD_WorkflowProcessor_ID=?)";
		PreparedStatement pstmt = null;
		int count = 0;
		int countEMails = 0;
		try
		{
			pstmt = DB.prepareStatement (sql, null);
			pstmt.setInt (1, m_model.getAD_Client_ID());
			pstmt.setInt (2, m_model.getAD_WorkflowProcessor_ID());
			ResultSet rs = pstmt.executeQuery ();
			while (rs.next ())
			{
				MWFActivity activity = new MWFActivity (getCtx(), rs, null);
				activity.setWFState (StateEngine.STATE_Completed);	
				// saves and calls MWFProcess.checkActivities();
				count++;
			}
			rs.close ();
			pstmt.close ();
			pstmt = null;
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, "wakeup", e);
		}
		m_summary.append("Wakeup #").append(count).append (" - ");
	}	//	wakeup
	
	/**
	 * 	Set/Increase Priority dynamically
	 */
	private void dynamicPriority()
	{
		//	suspened activities with dynamic priority node
		String sql = "SELECT * "
			+ "FROM AD_WF_Activity a "
			+ "WHERE Processed='N' AND WFState='OS'"	//	suspended
			+ " AND EXISTS (SELECT * FROM AD_Workflow wf"
				+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
				+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID AND wf.AD_WorkflowProcessor_ID=?"
				+ " AND wfn.DynPriorityUnit IS NOT NULL AND wfn.DynPriorityChange IS NOT NULL)";
		PreparedStatement pstmt = null;
		int count = 0;
		int countEMails = 0;
		try
		{
			pstmt = DB.prepareStatement (sql, null);
			pstmt.setInt(1, m_model.getAD_WorkflowProcessor_ID());
			ResultSet rs = pstmt.executeQuery ();
			while (rs.next ())
			{
				MWFActivity activity = new MWFActivity (getCtx(), rs, null);
				if (activity.getDynPriorityStart() == 0)
					activity.setDynPriorityStart(activity.getPriority());
				long ms = System.currentTimeMillis() - activity.getCreated().getTime();
				MWFNode node = activity.getNode();
				int prioDiff = node.calculateDynamicPriority ((int)(ms / 1000));
				activity.setPriority(activity.getDynPriorityStart() + prioDiff);
				activity.save();
				count++;
			}
			rs.close ();
			pstmt.close ();
			pstmt = null;
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, sql, e);
		}
		m_summary.append("DynPriority #").append(count).append (" - ");
		    
		//	Cleanup
		try
		{
			if (pstmt != null)
				pstmt.close ();
			pstmt = null;
		}
		catch (Exception e)
		{
			pstmt = null;
		}
	}	//	setPriority
	
	
	/**
	 * 	Send Alerts
	 */
	private void sendAlerts()
	{
		//	Alert over Priority
		if (m_model.getAlertOverPriority() > 0)
		{
			String sql = "SELECT * "
				+ "FROM AD_WF_Activity a "
				+ "WHERE Processed='N' AND WFState='OS'"	//	suspended
				+ " AND Priority >= ?"				//	##1
				+ " AND (DateLastAlert IS NULL";
			if (m_model.getRemindDays() > 0)
				sql += " OR (DateLastAlert+" + m_model.getRemindDays() 
					+ ") < SysDate";
			sql += ") AND EXISTS (SELECT * FROM AD_Workflow wf "
					+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
					+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID"
					+ " AND wf.AD_WorkflowProcessor_ID IS NULL OR wf.AD_WorkflowProcessor_ID=?)";
			int count = 0;
			int countEMails = 0;
			try
			{
				PreparedStatement pstmt = DB.prepareStatement(sql, null);
				pstmt.setInt (1, m_model.getAlertOverPriority());
				pstmt.setInt (2, m_model.getAD_WorkflowProcessor_ID());
				ResultSet rs = pstmt.executeQuery();
				while (rs.next())
				{
					MWFActivity activity = new MWFActivity (getCtx(), rs, null);
					boolean escalate = activity.getDateLastAlert() != null; 
					countEMails += sendEmail (activity, "ActivityOverPriority",
						escalate, true);
					activity.setDateLastAlert(new Timestamp(System.currentTimeMillis()));
					activity.save();
					count++;
				}
				rs.close();
				pstmt.close();
			}
			catch (SQLException e)
			{
				log.log(Level.SEVERE, "(Priority) - " + sql, e);
			}
			m_summary.append("OverPriority #").append(count);
			if (countEMails > 0)
				m_summary.append(" (").append(countEMails).append(" EMail)");
			m_summary.append (" - ");
		}	//	Alert over Priority

		/**
		 * 	Over End Wait
		 */
		String sql = "SELECT * "
			+ "FROM AD_WF_Activity a "
			+ "WHERE Processed='N' AND WFState='OS'"	//	suspended
			+ " AND EndWaitTime > SysDate"
			+ " AND (DateLastAlert IS NULL";
		if (m_model.getRemindDays() > 0)
			sql += " OR (DateLastAlert+" + m_model.getRemindDays() 
				+ ") < SysDate";
		sql += ") AND EXISTS (SELECT * FROM AD_Workflow wf "
				+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
				+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID"
				+ " AND wfn.Action<>'Z'"	//	not sleeping
				+ " AND wf.AD_WorkflowProcessor_ID IS NULL OR wf.AD_WorkflowProcessor_ID=?)";
		PreparedStatement pstmt = null;
		int count = 0;
		int countEMails = 0;
		try
		{
			pstmt = DB.prepareStatement (sql, null);
			pstmt.setInt(1, m_model.getAD_WorkflowProcessor_ID());
			ResultSet rs = pstmt.executeQuery ();
			while (rs.next ())
			{
				MWFActivity activity = new MWFActivity (getCtx(), rs, null);
				boolean escalate = activity.getDateLastAlert() != null; 
				countEMails += sendEmail (activity, "ActivityEndWaitTime", 
					escalate, false);
				activity.setDateLastAlert(new Timestamp(System.currentTimeMillis()));
				activity.save();
				count++;
			}
			rs.close ();
			pstmt.close ();
			pstmt = null;
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, "(EndWaitTime) - " + sql, e);
		}
		m_summary.append("EndWaitTime #").append(count);
		if (countEMails > 0)
			m_summary.append(" (").append(countEMails).append(" EMail)");
		m_summary.append (" - ");

		/**
		 *  Send inactivity alerts
		 */
		if (m_model.getInactivityAlertDays() > 0)
		{
			sql = "SELECT * "
				+ "FROM AD_WF_Activity a "
				+ "WHERE Processed='N' AND WFState='OS'"	//	suspended
				+ " AND (Updated+" + m_model.getInactivityAlertDays() + ") < SysDate"
				+ " AND (DateLastAlert IS NULL";
			if (m_model.getRemindDays() > 0)
				sql += " OR (DateLastAlert+" + m_model.getRemindDays() 
					+ ") < SysDate";
			sql += ") AND EXISTS (SELECT * FROM AD_Workflow wf "
					+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
					+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID"
					+ " AND wf.AD_WorkflowProcessor_ID IS NULL OR wf.AD_WorkflowProcessor_ID=?)";
			count = 0;
			countEMails = 0;
			try
			{
				pstmt = DB.prepareStatement(sql, null);
				pstmt.setInt (1, m_model.getAD_WorkflowProcessor_ID());
				ResultSet rs = pstmt.executeQuery();
				while (rs.next())
				{
					MWFActivity activity = new MWFActivity (getCtx(), rs, null);
					boolean escalate = activity.getDateLastAlert() != null; 
					countEMails += sendEmail (activity, "ActivityInactivity",
						escalate, false);
					activity.setDateLastAlert(new Timestamp(System.currentTimeMillis()));
					activity.save();
					count++;
				}
				rs.close();
				pstmt.close();
			}
			catch (SQLException e)
			{
				log.log(Level.SEVERE, "(Inactivity): " + sql, e);
			}
			m_summary.append("Inactivity #").append(count);
			if (countEMails > 0)
				m_summary.append(" (").append(countEMails).append(" EMail)");
			m_summary.append (" - ");
		}	//	Inactivity

		
		//	Cleanup
		try
		{
			if (pstmt != null)
				pstmt.close ();
			pstmt = null;
		}
		catch (Exception e)
		{
			pstmt = null;
		}
	}	//	sendAlerts
	
	/**
	 *  Send Alert EMail
	 *  @param activity activity
	 *  @param AD_Message message
	 * 	@return number of mails sent
	 */
	private int sendEmail (MWFActivity activity, String AD_Message,
		boolean toProcess, boolean toSupervisor)
	{
		if (m_client == null || m_client.getAD_Client_ID() != activity.getAD_Client_ID())
			m_client = MClient.get(getCtx(), activity.getAD_Client_ID());
			
		MWFProcess process = new MWFProcess (getCtx(), activity.getAD_WF_Process_ID(), null);

		String subjectVar = activity.getNode().getName();
		String message = activity.getTextMsg();
		if (message == null || message.length() == 0)
			message = process.getTextMsg();
		File pdf = null; 
		PO po = activity.getPO();
		if (po instanceof DocAction)
		{
			message = ((DocAction)po).getDocumentInfo() + "\n" + message;
			pdf = ((DocAction)po).createPDF();
		}
		
		//  Inactivity Alert: Workflow Activity {0}
		String subject = Msg.getMsg(m_client.getAD_Language(), AD_Message, 
			new Object[] {subjectVar});
		
		//	Prevent duplicates
		ArrayList<Integer> list = new ArrayList<Integer>();
		int counter = 0;
		
		//	To Activity Owner
		if (m_client.sendEMail(activity.getAD_User_ID(), subject, message, pdf))
			counter++;
		list.add (new Integer(activity.getAD_User_ID()));

		//	To Process Owner
		if (toProcess
			&& process.getAD_User_ID() != activity.getAD_User_ID())
		{
			if (m_client.sendEMail(process.getAD_User_ID(), subject, message, pdf))
				counter++;
			list.add (new Integer(process.getAD_User_ID()));
		}
		
		//	To Activity Responsible
		MWFResponsible responsible = MWFResponsible.get(getCtx(), activity.getAD_WF_Responsible_ID());
		counter += sendAlertToResponsible (responsible, list, process,
			subject, message, pdf);
		
		//	To Process Responsible
		if (toProcess
			&& process.getAD_WF_Responsible_ID() != activity.getAD_WF_Responsible_ID())
		{
			responsible = MWFResponsible.get(getCtx(), process.getAD_WF_Responsible_ID());
			counter += sendAlertToResponsible (responsible, list, process,
				subject, message, pdf);
		}
		
		//	Processor SuperVisor
		if (toSupervisor 
			&& m_model.getSupervisor_ID() != 0
			&& !list.contains(new Integer(m_model.getSupervisor_ID())))
		{
			if (m_client.sendEMail(m_model.getSupervisor_ID(), subject, message, pdf))
				counter++;
			list.add (new Integer(m_model.getSupervisor_ID()));
		}

		return counter;
	}   //  sendAlert
	
	/**
	 * 	Send Alert To Responsible
	 *	@param responsible responsible
	 *	@param list list of already sent users
	 *	@param process process
	 *	@param subject subject
	 *	@param message message
	 *	@param pdf optional pdf
	 *	@return number of mail sent
	 */
	private int sendAlertToResponsible (MWFResponsible responsible, 
		ArrayList<Integer> list, MWFProcess process,
		String subject, String message, File pdf)
	{
		int counter = 0;
		if (responsible.isInvoker())
			;
		//	Human
		else if (MWFResponsible.RESPONSIBLETYPE_Human.equals(responsible.getResponsibleType())
			&& responsible.getAD_User_ID() != 0
			&& !list.contains(new Integer(responsible.getAD_User_ID())))
		{
			if (m_client.sendEMail(responsible.getAD_User_ID(), subject, message, pdf))
				counter++;
			list.add (new Integer(responsible.getAD_User_ID()));
		}
		//	Org of the Document
		else if (MWFResponsible.RESPONSIBLETYPE_Organization.equals(responsible.getResponsibleType()))
		{
			PO document = process.getPO();
			if (document != null)
			{
				MOrgInfo org = MOrgInfo.get (getCtx(), document.getAD_Org_ID());
				if (org.getSupervisor_ID() != 0
					&& !list.contains(new Integer(org.getSupervisor_ID())))
				{
					if (m_client.sendEMail(org.getSupervisor_ID(), subject, message, pdf))
						counter++;
					list.add (new Integer(org.getSupervisor_ID()));
				}
			}
		}
		//	Role
		else if (MWFResponsible.RESPONSIBLETYPE_Role.equals(responsible.getResponsibleType())
			&& responsible.getAD_Role_ID() != 0)
		{
			MUserRoles[] userRoles = MUserRoles.getOfRole(getCtx(), responsible.getAD_Role_ID());
			for (int i = 0; i < userRoles.length; i++)
			{
				MUserRoles roles = userRoles[i];
				int AD_User_ID = roles.getAD_User_ID();
				if (!list.contains(new Integer(AD_User_ID)))
				{
					if (m_client.sendEMail(AD_User_ID, subject, message, pdf))
						counter++;
					list.add (new Integer(AD_User_ID));
				}
			}
		}
		return counter;
	}	//	sendAlertToResponsible
	
	
	/**
	 * 	Get Server Info
	 *	@return info
	 */
	public String getServerInfo()
	{
		return "#" + p_runCount + " - Last=" + m_summary.toString();
	}	//	getServerInfo

}	//	WorkflowProcessor

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -