📄 mwfactivity.java
字号:
} // 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 + -