Workflow Guard-Skripte#
Workflow Guard-Skripte werden Zustandsübergängen im Workflow zugewiesen. Sie prüfen etwas und stoppen den Zustandsübergang, wenn die Prüfung ein Nichteinhalten der Prüfbedingung ergeben hat.
Validierung eines Checkbox-Attributs#
package script.workflowGuard
import com.aurel.track.admin.customize.scripting.BINDING_PARAMS;
import com.aurel.track.admin.customize.treeConfig.field.FieldBL
import com.aurel.track.beans.TFieldBean
import com.aurel.track.beans.TWorkItemBean
public class CheckBoxValidator {
/**
* Workflow guard script example
* @param inputBinding
* @return
*/
public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
TFieldBean checkBoxField = FieldBL.loadByName("checkBoxFieldName");
if (checkBoxField!=null) {
Integer fieldID = checkBoxField.getObjectID();
TWorkItemBean workItemBean = inputBinding.get("item");
Boolean isChecked = workItemBean.getAttribute(fieldID);
inputBinding.put(BINDING_PARAMS.GUARD_PASSED, isChecked!=null && isChecked.booleanValue());
}
return inputBinding;
}
}
Prüfung, ob Vorgänger fertig#
Das basiert auf Vorgänger-Nachfolger-Verknüpfungen. Wenn der Vorgänger einen bestimmten Zustand erreicht hat, darf der Zustandsübergang stattfinden.
package script.workflowGuard
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.admin.customize.scripting.BINDING_PARAMS;
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TStateBean
import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.beans.TWorkItemLinkBean
import com.aurel.track.errors.ErrorData
import com.aurel.track.fieldType.runtime.base.LookupContainer
import com.aurel.track.fieldType.runtime.base.WorkItemContext
import com.aurel.track.item.ItemBL
import com.aurel.track.item.link.ItemLinkBL
import com.aurel.track.resources.LocalizeUtil
public class PredecessorReady {
/**
* Prevents the status change related to a guard if a predecessor, having other status than the configured, is found
* @param inputBinding
* @return
*/
public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
Integer itemID = workItemBean.getObjectID()
TPersonBean personBean = (TPersonBean)inputBinding.get("user")
Locale locale = (Locale)inputBinding.get("locale")
List<ErrorData> errorList = new ArrayList<>()
//look up the linktype ID in Link types config, ID column
Integer linkTypeID = 4
// 1=Unidirectional outward and bidirectional links,
// 2=Unidirectional inward (MsProject)
Integer linkDirection = 2
List<TWorkItemLinkBean> itemLinkBeans = ItemLinkBL.loadBySuccAndLinkType(itemID,
linkTypeID, linkDirection, true)
//alternatively look up target state(s) by other criteria
boolean notDonePredecessorFound = false;
if (itemLinkBeans!=null && itemLinkBeans.size()>0) {
//System.out.println("Linked items found: " + itemLinkBeans.size())
TStateBean doneStatusBean = StatusBL.loadByLabel("erledigt", Locale.GERMAN)
if (doneStatusBean!=null) {
//System.out.println("Done status found: " + doneStatusBean.getObjectID())
for (itemLinkBean in itemLinkBeans) {
Integer predecessor = itemLinkBean.getLinkPred()
TWorkItemBean linkedItemBean = ItemBL.loadWorkItemSystemAttributes(predecessor)
Integer status = linkedItemBean.getStateID()
if (!status.equals(doneStatusBean.getObjectID())) {
//System.out.println("Predecessor " + linkedItemBean.getObjectID() + " " + linkedItemBean.getSynopsis() + " with other status found. Exclude the transition")
notDonePredecessorFound = true
break;
}
}
}
}
inputBinding.put(BINDING_PARAMS.GUARD_PASSED, !notDonePredecessorFound);
return inputBinding;
}
}