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

📄 mwfactivity.java

📁 大家共享愉快, 共享愉快, 共享愉快, 共享愉快,共享愉快
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	}	//	getWFStateText
	
	/**
	 * 	Set Responsible and User from Process / Node
	 *	@param process process
	 */
	private void setResponsible (MWFProcess process)
	{
		//	Responsible
		int AD_WF_Responsible_ID = getNode().getAD_WF_Responsible_ID();
		if (AD_WF_Responsible_ID == 0)	//	not defined on Node Level
			AD_WF_Responsible_ID = process.getAD_WF_Responsible_ID();
		setAD_WF_Responsible_ID (AD_WF_Responsible_ID);
		MWFResponsible resp = getResponsible();
		
		//	User - Directly responsible
		int AD_User_ID = resp.getAD_User_ID();
		//	Invoker - get Sales Rep or last updater of document
		if (AD_User_ID == 0 && resp.isInvoker())
			AD_User_ID = process.getAD_User_ID();
		//
		setAD_User_ID(AD_User_ID);
	}	//	setResponsible
	
	/**
	 * 	Get Responsible
	 *	@return responsible
	 */
	public MWFResponsible getResponsible()
	{
		MWFResponsible resp = MWFResponsible.get(getCtx(), getAD_WF_Responsible_ID());
		return resp;
	}	//	isInvoker

	/**
	 * 	Is Invoker (no user & no role)
	 *	@return true if invoker
	 */
	public boolean isInvoker()
	{
		return getResponsible().isInvoker();
	}	//	isInvoker

	/**
	 * 	Get Approval User.
	 * 	If the returned user is the same, the document is approved.
	 *	@param AD_User_ID starting User
	 *	@param C_Currency_ID currency
	 *	@param amount amount
	 *	@param AD_Org_ID document organization
	 *	@param ownDocument the document is owned by AD_User_ID
	 *	@return AD_User_ID - if -1 no Approver
	 */
	public int getApprovalUser (int AD_User_ID, 
			int C_Currency_ID, BigDecimal amount, 
			int AD_Org_ID, boolean ownDocument)
	{
		//	Nothing to approve
		if (amount == null 
			|| amount.signum() == 0)
			return AD_User_ID;
		
		//	Starting user
		MUser user = MUser.get(getCtx(), AD_User_ID);
		log.info("For User=" + user 
			+ ", Amt=" + amount 
			+ ", Own=" + ownDocument);

		MUser oldUser = null;
		while (user != null)
		{
			if (user.equals(oldUser))
			{
				log.info("Loop - " + user.getName());
				return -1;
			}
			oldUser = user;
			log.fine("User=" + user.getName());
			//	Get Roles of User
			MRole[] roles = user.getRoles(AD_Org_ID);
			for (int i = 0; i < roles.length; i++)
			{
				MRole role = roles[i];
				if (ownDocument && !role.isCanApproveOwnDoc())
					continue;	//	find a role with allows them to approve own
				BigDecimal roleAmt = role.getAmtApproval();
				if (roleAmt == null || roleAmt.signum() == 0)
					continue;
				if (C_Currency_ID != role.getC_Currency_ID()	
					&& role.getC_Currency_ID() != 0)			//	No currency = amt only
				{
					roleAmt =  MConversionRate.convert(getCtx(),//	today & default rate 
						roleAmt, role.getC_Currency_ID(), 
						C_Currency_ID, getAD_Client_ID(), AD_Org_ID);
					if (roleAmt == null || roleAmt.signum() == 0)
						continue;
				}
				boolean approved = amount.compareTo(roleAmt) <= 0;
				log.fine("Approved=" + approved 
					+ " - User=" + user.getName() + ", Role=" + role.getName()
					+ ", ApprovalAmt=" + roleAmt);
				if (approved)
					return user.getAD_User_ID();
			}
			
			//	**** Find next User 
			//	Get Supervisor
			if (user.getSupervisor_ID() != 0)
			{
				user = MUser.get(getCtx(), user.getSupervisor_ID());
				log.fine("Supervisor: " + user.getName()); 
			}
			else
			{
				log.fine("No Supervisor"); 
				MOrg org = MOrg.get (getCtx(), AD_Org_ID);
				MOrgInfo orgInfo = org.getInfo();
				//	Get Org Supervisor
				if (orgInfo.getSupervisor_ID() != 0)
				{
					user = MUser.get(getCtx(), orgInfo.getSupervisor_ID());
					log.fine("Org=" + org.getName() + ",Supervisor: " + user.getName()); 
				}
				else
				{
					log.fine("No Org Supervisor"); 
					//	Get Parent Org Supervisor
					if (orgInfo.getParent_Org_ID() != 0)
					{
						org = MOrg.get (getCtx(), orgInfo.getParent_Org_ID());
						orgInfo = org.getInfo();
						if (orgInfo.getSupervisor_ID() != 0)
						{
							user = MUser.get(getCtx(), orgInfo.getSupervisor_ID());
							log.fine("Parent Org Supervisor: " + user.getName()); 
						}
					}
				}
			}	//	No Supervisor
			
		}	//	while there is a user to approve
		
		log.fine("No user found"); 
		return -1;
	}	//	getApproval

	
	/**************************************************************************
	 * 	Execute Work.
	 * 	Called from MWFProcess.startNext
	 * 	Feedback to Process via setWFState -> checkActivities
	 */
	public void run()
	{
		log.info ("Node=" + getNode());
		m_newValue = null;
		if (!m_state.isValidAction(StateEngine.ACTION_Start))
		{
			setTextMsg("State=" + getWFState() + " - cannot start");
			setWFState(StateEngine.STATE_Terminated);
			return;
		}
		//
		setWFState(StateEngine.STATE_Running);
		Trx trx = Trx.get(Trx.createTrxName("WF"), true);
		//
		try
		{
			if (getNode().get_ID() == 0)
			{
				setTextMsg("Node not found - AD_WF_Node_ID=" + getAD_WF_Node_ID());
				setWFState(StateEngine.STATE_Aborted);
				return;
			}
			//	Do Work
			/****	Trx Start	****/
			boolean done = performWork(trx);
			setWFState (done ? StateEngine.STATE_Completed : StateEngine.STATE_Suspended);
			/****	Trx End		****/
			trx.commit();
			trx.close();
			if (m_postImmediate != null)
				postImmediate();
		}
		catch (Exception e)
		{
			log.log(Level.WARNING, "" + getNode(), e);
			/****	Trx Rollback	****/
			trx.rollback();
			trx.close();
			//
			if (e.getCause() != null)
				log.log(Level.WARNING, "Cause", e.getCause());
			String processMsg = e.getLocalizedMessage();
			if (processMsg == null || processMsg.length() == 0)
				processMsg = e.getMessage();
			setTextMsg(processMsg);
			addTextMsg(e);
			setWFState (StateEngine.STATE_Terminated);
		}
	}	//	run
	
	
	/**
	 * 	Perform Work.
	 * 	Set Text Msg.
	 *	@return true if completed, false otherwise
	 *	@throws Exception if error
	 */
	private boolean performWork (Trx trx) throws Exception
	{
		log.info (m_node + " [" + trx.getTrxName() + "]");
		m_postImmediate = null;
		if (m_node.getPriority() != 0)		//	overwrite priority if defined
			setPriority(m_node.getPriority());
		String action = m_node.getAction();
		
		/******	Sleep (Start/End)			******/
		if (MWFNode.ACTION_WaitSleep.equals(action))
		{
			log.fine("Sleep:WaitTime=" + m_node.getWaitTime());
			if (m_node.getWaitingTime() == 0)
				return true;	//	done
			Calendar cal = Calendar.getInstance();
			cal.add(m_node.getDurationCalendarField(), m_node.getWaitTime());
			setEndWaitTime(new Timestamp(cal.getTimeInMillis()));
			return false;		//	not done
		}
		
		/******	Document Action				******/
		else if (MWFNode.ACTION_DocumentAction.equals(action))
		{
			log.fine("DocumentAction=" + m_node.getDocAction());
			getPO(trx);
			if (m_po == null)
				throw new Exception("Persistent Object not found - AD_Table_ID=" 
					+ getAD_Table_ID() + ", Record_ID=" + getRecord_ID());
			m_po.set_TrxName(trx.getTrxName());
			boolean success = false;
			String processMsg = null;
			if (m_po instanceof DocAction)
			{
				DocAction doc = (DocAction)m_po;
				//
				success = doc.processIt (m_node.getDocAction());	//	** Do the work
				setTextMsg(doc.getSummary());
				processMsg = doc.getProcessMsg();
				//	Post Immediate
				if (success && DocAction.ACTION_Complete.equals(m_node.getDocAction()))
				{
					MClient client = MClient.get(doc.getCtx(), doc.getAD_Client_ID());
					if (client.isPostImmediate())
						m_postImmediate = doc;
				}
				//
				if (m_process != null)
					m_process.setProcessMsg(processMsg);
			}
			else
				throw new IllegalStateException("Persistent Object not DocAction - "
					+ m_po.getClass().getName()
					+ " - AD_Table_ID=" + getAD_Table_ID() + ", Record_ID=" + getRecord_ID());
			//
			if (!m_po.save())
			{
				success = false;
				processMsg = "SaveError";
			}
			if (!success)
			{
				if (processMsg == null || processMsg.length() == 0)
					processMsg = "PerformWork Error - " + m_node.toStringX();
				throw new Exception(processMsg);
			}
			return success;
		}	//	DocumentAction
		
		/******	Report						******/
		else if (MWFNode.ACTION_AppsReport.equals(action))
		{
			log.fine("Report:AD_Process_ID=" + m_node.getAD_Process_ID());
			//	Process
			MProcess process = MProcess.get(getCtx(), m_node.getAD_Process_ID());
			if (!process.isReport() || process.getAD_ReportView_ID() == 0)
				throw new IllegalStateException("Not a Report AD_Process_ID=" + m_node.getAD_Process_ID());
			//
			ProcessInfo pi = new ProcessInfo (m_node.getName(true), m_node.getAD_Process_ID(),
				getAD_Table_ID(), getRecord_ID());
			pi.setAD_User_ID(getAD_User_ID());
			pi.setAD_Client_ID(getAD_Client_ID());
			MPInstance pInstance = new MPInstance(process, getRecord_ID());
			fillParameter(pInstance, trx);
			pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID());
			//	Report
			ReportEngine re = ReportEngine.get(getCtx(), pi);
			if (re == null)
				throw new IllegalStateException("Cannot create Report AD_Process_ID=" + m_node.getAD_Process_ID());
			File report = re.getPDF();
			//	Notice
			int AD_Message_ID = 753;		//	HARDCODED WorkflowResult
			MNote note = new MNote(getCtx(), AD_Message_ID, getAD_User_ID(), trx.getTrxName());
			note.setTextMsg(m_node.getName(true));
			note.setDescription(m_node.getDescription(true));
			note.setRecord(getAD_Table_ID(), getRecord_ID());
			note.save();
			//	Attachment
			MAttachment attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), get_TrxName());
			attachment.addEntry(report);
			attachment.setTextMsg(m_node.getName(true));
			attachment.save();
			return true;
		}
		
		/******	Process						******/
		else if (MWFNode.ACTION_AppsProcess.equals(action))
		{
			log.fine("Process:AD_Process_ID=" + m_node.getAD_Process_ID());
			//	Process
			MProcess process = MProcess.get(getCtx(), m_node.getAD_Process_ID());
			//
			ProcessInfo pi = new ProcessInfo (m_node.getName(true), m_node.getAD_Process_ID(),
				getAD_Table_ID(), getRecord_ID());
			pi.setAD_User_ID(getAD_User_ID());
			pi.setAD_Client_ID(getAD_Client_ID());
			MPInstance pInstance = new MPInstance(process, getRecord_ID());
			fillParameter(pInstance, trx);
			pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID());
			return process.processIt(pi, trx);
		}
		
		/******	TODO Start Task				******/
		else if (MWFNode.ACTION_AppsTask.equals(action))
		{
			log.warning ("Task:AD_Task_ID=" + m_node.getAD_Task_ID());
		}
		
		/******	EMail						******/
		else if (MWFNode.ACTION_EMail.equals(action))
		{
			log.fine ("EMail:EMailRecipient=" + m_node.getEMailRecipient());
			getPO(trx);
			if (m_po == null)
				throw new Exception("Persistent Object not found - AD_Table_ID=" 
					+ getAD_Table_ID() + ", Record_ID=" + getRecord_ID());
			if (m_po instanceof DocAction)
			{
				m_emails = new ArrayList<String>();
				sendEMail();
				setTextMsg(m_emails.toString());
			}
			return true;	//	done
		}	//	EMail
		
		/******	Set Variable				******/
		else if (MWFNode.ACTION_SetVariable.equals(action))
		{
			String value = m_node.getAttributeValue();
			log.fine("SetVariable:AD_Column_ID=" + m_node.getAD_Column_ID()
				+ " to " +  value);
			M_Column column = m_node.getColumn();
			int dt = column.getAD_Reference_ID();
			return setVariable (value, dt, null);
		}	//	SetVariable
		
		/******	TODO Start WF Instance		******/
		else if (MWFNode.ACTION_SubWorkflow.equals(action))
		{
			log.warning ("Workflow:AD_Workflow_ID=" + m_node.getAD_Workflow_ID());
		}
		
		/******	User Choice					******/
		else if (MWFNode.ACTION_UserChoice.equals(action))
		{
			log.fine("UserChoice:AD_Column_ID=" + m_node.getAD_Column_ID());
			//	Approval
			if (m_node.isUserApproval() 
				&& getPO() instanceof DocAction)
			{
				DocAction doc = (DocAction)m_po;
				boolean autoApproval = false;
				//	Approval Hierarchy
				if (isInvoker())
				{
					//	Set Approver
					int startAD_User_ID = getAD_User_ID();
					if (startAD_User_ID == 0)
						startAD_User_ID = doc.getDoc_User_ID();
					int nextAD_User_ID = getApprovalUser(startAD_User_ID, 
						doc.getC_Currency_ID(), doc.getApprovalAmt(),
						doc.getAD_Org_ID(), 
						startAD_User_ID == doc.getDoc_User_ID());	//	own doc
					//	same user = approved
					autoApproval = startAD_User_ID == nextAD_User_ID;
					if (!autoApproval)
						setAD_User_ID(nextAD_User_ID);
				}
				else	//	fixed Approver
				{
					MWFResponsible resp = getResponsible();
					autoApproval = resp.getAD_User_ID() == getAD_User_ID();
					if (!autoApproval && resp.getAD_User_ID() != 0)
						setAD_User_ID(resp.getAD_User_ID());
				}
				if (autoApproval
					&& doc.processIt(DocAction.ACTION_Approve)
					&& doc.save())
					return true;	//	done
			}	//	approval
			return false;	//	wait for user
		}
		/******	User Workbench				******/
		else if (MWFNode.ACTION_UserWorkbench.equals(action))
		{
			log.fine("Workbench:?");
			return false;
		}
		/******	User Form					******/
		else if (MWFNode.ACTION_UserForm.equals(action))
		{
			log.fine("Form:AD_Form_ID=" + m_node.getAD_Form_ID());
			return false;
		}
		/******	User Window					******/
		else if (MWFNode.ACTION_UserWindow.equals(action))
		{
			log.fine("Window:AD_Window_ID=" + m_node.getAD_Window_ID());
			return false;
		}
		//
		throw new IllegalArgumentException("Invalid Action (Not Implemented) =" + action);
	}	//	performWork
	
	/**
	 * 	Set Variable
	 *	@param value new Value
	 *	@param displayType display type
	 *	@param textMsg optional Message
	 *	@return true if set
	 *	@throws Exception if error
	 */
	private boolean setVariable(String value, int displayType, String textMsg) throws Exception
	{
		m_newValue = null;
		getPO();
		if (m_po == null)
			throw new Exception("Persistent Object not found - AD_Table_ID=" 
				+ getAD_Table_ID() + ", Record_ID=" + getRecord_ID());
		//	Set Value
		Object dbValue = null;
		if (value == null)
			;
		else if (displayType == DisplayType.YesNo)
			dbValue = new Boolean("Y".equals(value));
		else if (DisplayType.isNumeric(displayType))
			dbValue = new BigDecimal (value);
		else
			dbValue = value;
		m_po.set_ValueOfColumn(getNode().getAD_Column_ID(), dbValue);
		m_po.save();
		if (!dbValue.equals(m_po.get_ValueOfColumn(getNode().getAD_Column_ID())))
			throw new Exception("Persistent Object not updated - AD_Table_ID=" 
				+ getAD_Table_ID() + ", Record_ID=" + getRecord_ID() 
				+ " - Should=" + value + ", Is=" + m_po.get_ValueOfColumn(m_node.getAD_Column_ID()));
		//	Info
		String msg = getNode().getAttributeName() + "=" + value;
		if (textMsg != null && textMsg.length() > 0)
			msg += " - " + textMsg;
		setTextMsg (msg);
		m_newValue = value;
		return true;
	}	//	setVariable
	
	/**
	 * 	Set User Choice
	 * 	@param AD_User_ID user
	 *	@param value new Value
	 *	@param displayType display type
	 *	@param textMsg optional Message
	 *	@return true if set
	 *	@throws Exception if error
	 */
	public boolean setUserChoice (int AD_User_ID, String value, int displayType, 
		String textMsg) throws Exception
	{
		//	Check if user approves own document when a role is reponsible
		if (getNode().isUserApproval() && getPO() instanceof DocAction)
		{
			DocAction doc = (DocAction)m_po;
			MUser user = new MUser (getCtx(), AD_User_ID, null);
			MRole[] roles = user.getRoles(m_po.getAD_Org_ID());
			boolean canApproveOwnDoc = false;
			for (int r = 0; r < roles.length; r++)
			{
				if (roles[r].isCanApproveOwnDoc())
				{
					canApproveOwnDoc = true;
					break;
				}	//	found a role which allows to approve own document
			}
			if (!canApproveOwnDoc)
			{
				String info = user.getName() + " cannot approve own document " + doc;
				addTextMsg(info);
				log.fine(info);
				return false;		//	ignore
			}
		}
		
		setWFState (StateEngine.STATE_Running);
		setAD_User_ID(AD_User_ID);
		boolean ok = setVariable (value, displayType, textMsg);
		if (!ok)
			return false;

		String newState = StateEngine.STATE_Completed;
		//	Approval
		if (getNode().isUserApproval() && getPO() instanceof DocAction)
		{
			DocAction doc = (DocAction)m_po;
			try
			{
				//	Not pproved
				if (!"Y".equals(value))

⌨️ 快捷键说明

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