[ 1741750 ] Atomic Workflow Activities + Making WFs more Predictable
This commit is contained in:
parent
7ddb37ce99
commit
c1bfcd4d66
|
@ -654,19 +654,35 @@ public class MUser extends X_AD_User
|
||||||
return m_roles;
|
return m_roles;
|
||||||
|
|
||||||
ArrayList<MRole> list = new ArrayList<MRole>();
|
ArrayList<MRole> list = new ArrayList<MRole>();
|
||||||
|
// 2007-06-08, matthiasO.
|
||||||
|
// Extension of sql query so that not only roles with org acces for this user
|
||||||
|
// are found but also roles which delegate org access to the user level where
|
||||||
|
// this user has access to the org in question
|
||||||
String sql = "SELECT * FROM AD_Role r "
|
String sql = "SELECT * FROM AD_Role r "
|
||||||
+ "WHERE r.IsActive='Y'"
|
+ "WHERE r.IsActive='Y'"
|
||||||
+ " AND EXISTS (SELECT * FROM AD_Role_OrgAccess ro"
|
|
||||||
+ " WHERE r.AD_Role_ID=ro.AD_Role_ID AND ro.IsActive='Y' AND ro.AD_Org_ID=?)"
|
|
||||||
+ " AND EXISTS (SELECT * FROM AD_User_Roles ur"
|
+ " AND EXISTS (SELECT * FROM AD_User_Roles ur"
|
||||||
+ " WHERE r.AD_Role_ID=ur.AD_Role_ID AND ur.IsActive='Y' AND ur.AD_User_ID=?) "
|
+ " WHERE r.AD_Role_ID=ur.AD_Role_ID AND ur.IsActive='Y' AND ur.AD_User_ID=?) "
|
||||||
|
+ " AND ("
|
||||||
|
+ " ("
|
||||||
|
+ " r.IsUseUserOrgAccess <> 'Y'"
|
||||||
|
+ " AND EXISTS (SELECT * FROM AD_Role_OrgAccess ro"
|
||||||
|
+ " WHERE r.AD_Role_ID=ro.AD_Role_ID AND ro.IsActive='Y' AND ro.AD_Org_ID=?)"
|
||||||
|
+ " ) OR "
|
||||||
|
+ " ("
|
||||||
|
+ " r.IsUseUserOrgAccess = 'Y'"
|
||||||
|
+ " AND EXISTS (SELECT * FROM AD_User_OrgAccess uo"
|
||||||
|
+ " WHERE uo.AD_User_ID=? AND uo.IsActive='Y' AND uo.AD_Org_ID=?)"
|
||||||
|
+ " )"
|
||||||
|
+ " ) "
|
||||||
+ "ORDER BY AD_Role_ID";
|
+ "ORDER BY AD_Role_ID";
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pstmt = DB.prepareStatement (sql, get_TrxName());
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
pstmt.setInt (1, AD_Org_ID);
|
pstmt.setInt (1, getAD_User_ID());
|
||||||
pstmt.setInt (2, getAD_User_ID());
|
pstmt.setInt (2, AD_Org_ID);
|
||||||
|
pstmt.setInt (3, getAD_User_ID());
|
||||||
|
pstmt.setInt (4, AD_Org_ID);
|
||||||
ResultSet rs = pstmt.executeQuery ();
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
while (rs.next ())
|
while (rs.next ())
|
||||||
list.add (new MRole(getCtx(), rs, get_TrxName()));
|
list.add (new MRole(getCtx(), rs, get_TrxName()));
|
||||||
|
|
|
@ -236,7 +236,8 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
|
|
||||||
// Inform Process
|
// Inform Process
|
||||||
if (m_process == null)
|
if (m_process == null)
|
||||||
m_process = new MWFProcess (getCtx(), getAD_WF_Process_ID(), null);
|
m_process = new MWFProcess (getCtx(), getAD_WF_Process_ID(),
|
||||||
|
m_trx == null ? null : m_trx.getTrxName());
|
||||||
m_process.checkActivities(m_trx == null ? null : m_trx.getTrxName());
|
m_process.checkActivities(m_trx == null ? null : m_trx.getTrxName());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -674,7 +675,8 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // No Supervisor
|
} // No Supervisor
|
||||||
|
//ownDocument should always be false for the next user
|
||||||
|
ownDocument = false;
|
||||||
} // while there is a user to approve
|
} // while there is a user to approve
|
||||||
|
|
||||||
log.fine("No user found");
|
log.fine("No user found");
|
||||||
|
@ -755,7 +757,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
addTextMsg(e);
|
addTextMsg(e);
|
||||||
setWFState (StateEngine.STATE_Terminated); // unlocks
|
setWFState (StateEngine.STATE_Terminated); // unlocks
|
||||||
// Set Document Status
|
// Set Document Status
|
||||||
if (m_po != null && m_docStatus != null)
|
if (m_po != null && m_po instanceof DocAction && m_docStatus != null)
|
||||||
{
|
{
|
||||||
m_po.load(null);
|
m_po.load(null);
|
||||||
DocAction doc = (DocAction)m_po;
|
DocAction doc = (DocAction)m_po;
|
||||||
|
@ -855,6 +857,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
log.fine("Report:AD_Process_ID=" + m_node.getAD_Process_ID());
|
log.fine("Report:AD_Process_ID=" + m_node.getAD_Process_ID());
|
||||||
// Process
|
// Process
|
||||||
MProcess process = MProcess.get(getCtx(), m_node.getAD_Process_ID());
|
MProcess process = MProcess.get(getCtx(), m_node.getAD_Process_ID());
|
||||||
|
process.set_TrxName(trx != null ? trx.getTrxName() : null);
|
||||||
if (!process.isReport() || process.getAD_ReportView_ID() == 0)
|
if (!process.isReport() || process.getAD_ReportView_ID() == 0)
|
||||||
throw new IllegalStateException("Not a Report AD_Process_ID=" + m_node.getAD_Process_ID());
|
throw new IllegalStateException("Not a Report AD_Process_ID=" + m_node.getAD_Process_ID());
|
||||||
//
|
//
|
||||||
|
@ -863,6 +866,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
pi.setAD_User_ID(getAD_User_ID());
|
pi.setAD_User_ID(getAD_User_ID());
|
||||||
pi.setAD_Client_ID(getAD_Client_ID());
|
pi.setAD_Client_ID(getAD_Client_ID());
|
||||||
MPInstance pInstance = new MPInstance(process, getRecord_ID());
|
MPInstance pInstance = new MPInstance(process, getRecord_ID());
|
||||||
|
pInstance.set_TrxName(trx != null ? trx.getTrxName() : null);
|
||||||
fillParameter(pInstance, trx);
|
fillParameter(pInstance, trx);
|
||||||
pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID());
|
pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID());
|
||||||
// Report
|
// Report
|
||||||
|
@ -937,7 +941,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
+ " to " + value);
|
+ " to " + value);
|
||||||
MColumn column = m_node.getColumn();
|
MColumn column = m_node.getColumn();
|
||||||
int dt = column.getAD_Reference_ID();
|
int dt = column.getAD_Reference_ID();
|
||||||
return setVariable (value, dt, null);
|
return setVariable (value, dt, null, trx);
|
||||||
} // SetVariable
|
} // SetVariable
|
||||||
|
|
||||||
/****** TODO Start WF Instance ******/
|
/****** TODO Start WF Instance ******/
|
||||||
|
@ -953,7 +957,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
log.fine("UserChoice:AD_Column_ID=" + m_node.getAD_Column_ID());
|
log.fine("UserChoice:AD_Column_ID=" + m_node.getAD_Column_ID());
|
||||||
// Approval
|
// Approval
|
||||||
if (m_node.isUserApproval()
|
if (m_node.isUserApproval()
|
||||||
&& getPO() instanceof DocAction)
|
&& getPO(trx) instanceof DocAction)
|
||||||
{
|
{
|
||||||
DocAction doc = (DocAction)m_po;
|
DocAction doc = (DocAction)m_po;
|
||||||
boolean autoApproval = false;
|
boolean autoApproval = false;
|
||||||
|
@ -1011,10 +1015,10 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
* @return true if set
|
* @return true if set
|
||||||
* @throws Exception if error
|
* @throws Exception if error
|
||||||
*/
|
*/
|
||||||
private boolean setVariable(String value, int displayType, String textMsg) throws Exception
|
private boolean setVariable(String value, int displayType, String textMsg, Trx trx) throws Exception
|
||||||
{
|
{
|
||||||
m_newValue = null;
|
m_newValue = null;
|
||||||
getPO();
|
getPO(trx);
|
||||||
if (m_po == null)
|
if (m_po == null)
|
||||||
throw new Exception("Persistent Object not found - AD_Table_ID="
|
throw new Exception("Persistent Object not found - AD_Table_ID="
|
||||||
+ getAD_Table_ID() + ", Record_ID=" + getRecord_ID());
|
+ getAD_Table_ID() + ", Record_ID=" + getRecord_ID());
|
||||||
|
@ -1030,7 +1034,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
dbValue = value;
|
dbValue = value;
|
||||||
m_po.set_ValueOfColumn(getNode().getAD_Column_ID(), dbValue);
|
m_po.set_ValueOfColumn(getNode().getAD_Column_ID(), dbValue);
|
||||||
m_po.save();
|
m_po.save();
|
||||||
if (!dbValue.equals(m_po.get_ValueOfColumn(getNode().getAD_Column_ID())))
|
if (dbValue != null && !dbValue.equals(m_po.get_ValueOfColumn(getNode().getAD_Column_ID())))
|
||||||
throw new Exception("Persistent Object not updated - AD_Table_ID="
|
throw new Exception("Persistent Object not updated - AD_Table_ID="
|
||||||
+ getAD_Table_ID() + ", Record_ID=" + getRecord_ID()
|
+ getAD_Table_ID() + ", Record_ID=" + getRecord_ID()
|
||||||
+ " - Should=" + value + ", Is=" + m_po.get_ValueOfColumn(m_node.getAD_Column_ID()));
|
+ " - Should=" + value + ", Is=" + m_po.get_ValueOfColumn(m_node.getAD_Column_ID()));
|
||||||
|
@ -1056,6 +1060,19 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
String textMsg) throws Exception
|
String textMsg) throws Exception
|
||||||
{
|
{
|
||||||
// Check if user approves own document when a role is reponsible
|
// Check if user approves own document when a role is reponsible
|
||||||
|
/*
|
||||||
|
* 2007-06-08, matthiasO.
|
||||||
|
* The following sequence makes sure that only users in roles which
|
||||||
|
* have the 'Approve own document flag' set can set the user choice
|
||||||
|
* of 'Y' (approve) or 'N' (reject).
|
||||||
|
* IMHO this is against the meaning of 'Approve own document': Why
|
||||||
|
* should a user who is faced with the task of approving documents
|
||||||
|
* generally be required to have the ability to approve his OWN
|
||||||
|
* documents? If the document to approve really IS his own document
|
||||||
|
* this will be respected when trying to find an approval user in
|
||||||
|
* the call to getApprovalUser(...) below.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
if (getNode().isUserApproval() && getPO() instanceof DocAction)
|
if (getNode().isUserApproval() && getPO() instanceof DocAction)
|
||||||
{
|
{
|
||||||
DocAction doc = (DocAction)m_po;
|
DocAction doc = (DocAction)m_po;
|
||||||
|
@ -1077,17 +1094,18 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
log.fine(info);
|
log.fine(info);
|
||||||
return false; // ignore
|
return false; // ignore
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
setWFState (StateEngine.STATE_Running);
|
setWFState (StateEngine.STATE_Running);
|
||||||
setAD_User_ID(AD_User_ID);
|
setAD_User_ID(AD_User_ID);
|
||||||
boolean ok = setVariable (value, displayType, textMsg);
|
Trx trx = ( get_TrxName() != null ) ? Trx.get(get_TrxName(), false) : null;
|
||||||
|
boolean ok = setVariable (value, displayType, textMsg, trx);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
String newState = StateEngine.STATE_Completed;
|
String newState = StateEngine.STATE_Completed;
|
||||||
// Approval
|
// Approval
|
||||||
if (getNode().isUserApproval() && getPO() instanceof DocAction)
|
if (getNode().isUserApproval() && getPO(trx) instanceof DocAction)
|
||||||
{
|
{
|
||||||
DocAction doc = (DocAction)m_po;
|
DocAction doc = (DocAction)m_po;
|
||||||
try
|
try
|
||||||
|
@ -1156,16 +1174,23 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
|
||||||
|| MUser.NOTIFICATIONTYPE_EMailPlusNotice.equals(NotificationType)) {
|
|| MUser.NOTIFICATIONTYPE_EMailPlusNotice.equals(NotificationType)) {
|
||||||
MClient client = MClient.get(getCtx(), doc.getAD_Client_ID());
|
MClient client = MClient.get(getCtx(), doc.getAD_Client_ID());
|
||||||
client.sendEMail(doc.getDoc_User_ID(), Msg.getMsg(getCtx(), "NotApproved")
|
client.sendEMail(doc.getDoc_User_ID(), Msg.getMsg(getCtx(), "NotApproved")
|
||||||
+ ": " + doc.getDocumentNo(), doc.getSummary() + "\n"
|
+ ": " + doc.getDocumentNo(),
|
||||||
+ doc.getProcessMsg() + "\n" + getTextMsg(), null);
|
(doc.getSummary() != null ? doc.getSummary() + "\n" : "" )
|
||||||
|
+ (doc.getProcessMsg() != null ? doc.getProcessMsg() + "\n" : "")
|
||||||
|
+ (getTextMsg() != null ? getTextMsg() : ""), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send Note
|
// Send Note
|
||||||
if (MUser.NOTIFICATIONTYPE_Notice.equals(NotificationType)
|
if (MUser.NOTIFICATIONTYPE_Notice.equals(NotificationType)
|
||||||
|| MUser.NOTIFICATIONTYPE_EMailPlusNotice.equals(NotificationType)) {
|
|| MUser.NOTIFICATIONTYPE_EMailPlusNotice.equals(NotificationType)) {
|
||||||
MNote note = new MNote(getCtx(), "NotApproved", doc.getDoc_User_ID(), null);
|
MNote note = new MNote(getCtx(), "NotApproved", doc.getDoc_User_ID(), null);
|
||||||
note.setTextMsg(doc.getSummary() + "\n" + doc.getProcessMsg() + "\n"
|
note.setTextMsg((doc.getSummary() != null ? doc.getSummary() + "\n" : "" )
|
||||||
+ getTextMsg());
|
+ (doc.getProcessMsg() != null ? doc.getProcessMsg() + "\n" : "")
|
||||||
|
+ (getTextMsg() != null ? getTextMsg() : ""));
|
||||||
|
// 2007-06-08, matthiasO.
|
||||||
|
// Add record information to the note, so that the user receiving the
|
||||||
|
// note can jump to the doc easily
|
||||||
|
note.setRecord(m_po.get_Table_ID(), m_po.get_ID());
|
||||||
note.save();
|
note.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,11 +141,13 @@ public class MWFResponsible extends X_AD_WF_Responsible
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// User not used
|
// User not used
|
||||||
if (!RESPONSIBLETYPE_Human.equals(getResponsibleType()) && getAD_User_ID() == 0)
|
if (!RESPONSIBLETYPE_Human.equals(getResponsibleType()) && getAD_User_ID() > 0)
|
||||||
setAD_User_ID(0);
|
setAD_User_ID(0);
|
||||||
|
|
||||||
// Role not used
|
// Role not used
|
||||||
if (!RESPONSIBLETYPE_Role.equals(getResponsibleType()) && getAD_Role_ID() == 0)
|
if (!RESPONSIBLETYPE_Role.equals(getResponsibleType()) && getAD_Role_ID() > 0)
|
||||||
setAD_Role_ID(0);
|
setAD_Role_ID(0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,10 @@ public class WFActivityManage extends SvrProcess
|
||||||
String msg = user.getName() + ": Abort";
|
String msg = user.getName() + ": Abort";
|
||||||
activity.setTextMsg(msg);
|
activity.setTextMsg(msg);
|
||||||
activity.setAD_User_ID(getAD_User_ID());
|
activity.setAD_User_ID(getAD_User_ID());
|
||||||
|
// 2007-06-14, matthiasO.
|
||||||
|
// Set the 'processed'-flag when an activity is aborted; not setting this flag
|
||||||
|
// will leave the activity in an "unmanagable" state
|
||||||
|
activity.setProcessed(true);
|
||||||
activity.setWFState(StateEngine.STATE_Aborted);
|
activity.setWFState(StateEngine.STATE_Aborted);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue