Workflow Activity-Skripte#

Workflow Activity-Skripte können im Workflow an Zustandsübergängen zugewiesen werden. Sie werden dann ausgeführt, wenn der Zustandsübergang stattfindet.

Kommentar hinzufügen#

package script.workflowActivity
import java.util.LinkedList
import java.util.List
import java.util.Map

import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.errors.ErrorData
import com.aurel.track.util.event.IEventHandler

public class CommentByReopen implements IEventHandler {

	private static String REOPEN_SEPARATOR  = 
	        "**************************REOPEN*******************************"

	/**
	 * Sets the comment field as required. If comment is entered,
	 * this will be added to the end of the description
	 * Could be used as workflow activity script,
	 * for example by reopening an item (leave the closed status)
	 * 
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		TWorkItemBean workItemBean = (TWorkItemBean)inputBinding.get("item")
		String comment = workItemBean.getComment()
		if (comment==null || comment.trim().length()==0) {
			List<ErrorData> errorList = new LinkedList<ErrorData>()
			errorList.add(new ErrorData("Comment is required by reopen"))
			inputBinding.put("errorList", errorList)
		} else {
			String description = workItemBean.getDescription()
			if (description==null) {
				description = ""
			}
			description = description + REOPEN_SEPARATOR + comment
			workItemBean.setDescription(description)
			workItemBean.setComment(null)
		}
		return inputBinding
	}
}

Gruppen je nach Bereich zuweisen#

Dieses Skript weist dem übergebenen Vorgang eine Gruppe als Editoren zu. Die Gruppe wird durch die Zuordnung WP_NAME_TO_GROUP_NAME definiert. Der Schlüssel der Map ist der Name des Arbeitsbereichs, der Wert ist der Gruppenname.

package script.workflowActivity
import org.apache.logging.log4j.Logger

import com.aurel.track.accessControl.AccessControlBL
import com.aurel.track.admin.customize.role.RoleBL
import com.aurel.track.admin.customize.scripting.BINDING_PARAMS
import com.aurel.track.admin.user.group.GroupMemberBL
import com.aurel.track.admin.user.person.PersonBL
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TProjectBean
import com.aurel.track.beans.TRoleBean
import com.aurel.track.beans.TWorkItemBean
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.consInf.WatcherRole
import com.aurel.track.item.itemDetailTab.watcher.AddWatcherBL
import com.aurel.track.item.itemDetailTab.watcher.WatcherList
import com.aurel.track.util.event.IEventHandler
import org.apache.logging.log4j.LogManager;

/**
 * This script assigns a group as consulted to the passed item.
 * The group is defined by WP_NAME_TO_GROUP_NAME map. 
 * The map key is the workspace name the value is the group name.
 * 
 * If the passed item belongs to a workspace which is defined above then it assigns the defined group as watcher.
 * @author BENCE
 *
 */
public class AddWatcherByWpAndGroupMapping implements IEventHandler {

	private static final Logger LOGGER = LogManager.getLogger(AddWatcherByWpAndGroupMapping.class);
	
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
//		Script configuration
		Map<String, String>WP_NAME_TO_GROUP_NAME = new HashMap<String, String>();
//		WP_NAME_TO_GROUP_NAME.put("Workspace name", "Group name");
//		End of script configuration.
		if(WP_NAME_TO_GROUP_NAME.isEmpty() == null) {
			return inputBinding;
		}
		WorkItemContext ctx = (WorkItemContext)inputBinding.get(BINDING_PARAMS.WORKITEM_CONTEXT)
		TWorkItemBean workItemBean = (TWorkItemBean)inputBinding.get(BINDING_PARAMS.ITEM)
		TPersonBean personBean = (TPersonBean)inputBinding.get(BINDING_PARAMS.USER)
		Locale locale = (Locale)inputBinding.get(BINDING_PARAMS.LOCALE)
		Integer workItemID = workItemBean.getObjectID()
		WatcherList watcherList = null;
		String targetProjectName = null;
		if(workItemID == null && ctx != null) {
			watcherList = ctx.getWatcherList();
		}
		TPersonBean targetGroup = null;
		if(ctx != null && ctx.getWorkItemBean() != null) {
			TProjectBean project = LookupContainer.getProjectBean(ctx.getWorkItemBean().getProjectID());
			if(project != null) {
				String groupName = WP_NAME_TO_GROUP_NAME.get(project.getLabel());
				if(groupName != null && !groupName.isEmpty()) {
					targetGroup = PersonBL.loadGroupByName(groupName);
				}
			}
		}
		LOGGER.debug("Target group name: " + (targetGroup != null ? targetGroup.getName() : "null"));
		if(targetGroup != null) {
			AddWatcherBL.save(workItemID, watcherList, WatcherRole.CONSULTANT, Arrays.asList(targetGroup.getObjectID()), personBean, locale);
		}else {
			LOGGER.warn("Group to add as watcher is null.");
		}
		return inputBinding
	}
}

Beobachter nach Rolle hinzufügen#

package script.workflowActivity
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger

import com.aurel.track.accessControl.AccessControlBL
import com.aurel.track.admin.customize.role.RoleBL
import com.aurel.track.admin.customize.scripting.BINDING_PARAMS
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TRoleBean
import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.fieldType.runtime.base.WorkItemContext
import com.aurel.track.item.consInf.WatcherRole
import com.aurel.track.item.history.HistoryLoaderBL
import com.aurel.track.item.itemDetailTab.watcher.AddWatcherBL
import com.aurel.track.item.itemDetailTab.watcher.WatcherList
import com.aurel.track.util.event.IEventHandler

public class AddWatchersByRole implements IEventHandler {

	private static final Logger LOGGER = LogManager.getLogger(AddWatchersByRole.class);

	/**
	 * Adds all persons having the role "Informed" in the item's workspace (i.e. potential readers),
	 * as actual readers of this item
	 * Could be used as workflow activity script,
	 * for example by reaching a certain status in the workflow
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext ctx = (WorkItemContext)inputBinding.get(BINDING_PARAMS.WORKITEM_CONTEXT)
		TWorkItemBean workItemBean = (TWorkItemBean)inputBinding.get(BINDING_PARAMS.ITEM)
		TPersonBean personBean = (TPersonBean)inputBinding.get(BINDING_PARAMS.USER)
		Locale locale = (Locale)inputBinding.get(BINDING_PARAMS.LOCALE)
		Integer workItemID = workItemBean.getObjectID()
		WatcherList watcherList = null;
		if (workItemID==null) {
			if(ctx!=null){
				watcherList = ctx.getWatcherList()
			}
		}
		TRoleBean roleBean = RoleBL.loadByName("Informed")
		if (roleBean!=null) {
			LOGGER.debug("Role " + roleBean.getLabel() + " found")
			Set<Integer> rolePersons = AccessControlBL.getPersonSetByProjectRole(workItemBean.getProjectID(), roleBean.getObjectID())
			LOGGER.debug("Persons in role " + rolePersons)
			AddWatcherBL.save(workItemID, watcherList, WatcherRole.INFORMANT, new ArrayList(rolePersons), personBean, locale);
		} else {
			LOGGER.debug("Role not found")
		}
		return inputBinding
	}
}

Weitere unkommentierte#

package script.workflowActivity
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.admin.user.person.PersonBL
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TStateBean
import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.errors.ErrorData
import com.aurel.track.fieldType.constants.SystemFields
import com.aurel.track.fieldType.runtime.base.WorkItemContext
import com.aurel.track.item.link.LinkedItemsStatusBL
import com.aurel.track.util.event.IEventHandler
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class ChangeChildrenAttribute implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(ChangeChildrenAttribute.class);
	/**
	 * Changes all child items' responsible from parent's old responsible to parent's new responsible
	 * Could be used as workflow activity script,
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		TWorkItemBean workItemBeanOriginal = workItemContext.getWorkItemBeanOriginal()
		Integer itemID = workItemBean.getObjectID()
		LOGGER.debug("ChangeChildrenAttribute called for {} {}", workItemBean.getSynopsis(), itemID)
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		Integer originalResponsibleID = workItemBeanOriginal.getResponsibleID()
		Integer newReponsibleID = workItemBean.getResponsibleID()
		if (!newReponsibleID.equals(originalResponsibleID)) {
			LOGGER.debug("Responsible change from {} to {}", originalResponsibleID, newReponsibleID)
			TPersonBean responsibleBean = PersonBL.loadByPrimaryKey(originalResponsibleID);
			boolean originalResponsibleIsGroup = false;
			if (responsibleBean!=null) {
				originalResponsibleIsGroup = responsibleBean.isGroup();
				LOGGER.debug("Original responsible is group: {}", originalResponsibleIsGroup)
			}
			if (originalResponsibleIsGroup) {
				List<ErrorData> errorList = LinkedItemsStatusBL.changeAttributeOfChildren(itemID, SystemFields.RESPONSIBLE,
					originalResponsibleID, newReponsibleID, personBean, locale)
				inputBinding.put("errorList", errorList)
			}
		}	
		return inputBinding
	}
	
}
package script.workflowActivity
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TStateBean
import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.errors.ErrorData
import com.aurel.track.fieldType.runtime.base.WorkItemContext
import com.aurel.track.item.link.LinkedItemsStatusBL
import com.aurel.track.util.event.IEventHandler
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class ChangeChildrenStatus implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(ChangeChildrenStatus.class);
	/**
	 * Changes all child items' status from "fromStatusBean" to "toStatusBean"
	 * only if they have no predecessor or the predecessor's status is "doneStatusBean"
	 * Could be used as workflow activity script,
	 * for example when the parent item reaches a certain status
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		Integer itemID = workItemBean.getObjectID()
		LOGGER.debug(String.format("ChangeChildrenStatus called for %s %d", workItemBean.getSynopsis(), itemID))
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		//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
		TStateBean fromStatusBean = StatusBL.loadByLabel("nicht bereit", Locale.GERMAN)
		Integer fromStatusID = null
		if (fromStatusBean!=null) {
			fromStatusID = fromStatusBean.getObjectID()
		}
		TStateBean toStatusBean = StatusBL.loadByLabel("bereit", Locale.GERMAN)
		Integer toStatusID = null
		if (toStatusBean!=null) {
			toStatusID = toStatusBean.getObjectID()
		}
		TStateBean doneStatusBean = StatusBL.loadByLabel("erledigt", Locale.GERMAN)
		Integer doneStatusID = null;
		if (doneStatusBean!=null) {
			doneStatusID = doneStatusBean.getObjectID();
		}
		if (toStatusID!=null) {
			List<ErrorData> errorList = LinkedItemsStatusBL.changeStatusOfOpenChildren(itemID,  
				linkTypeID, linkDirection, fromStatusID, toStatusID, doneStatusID, personBean, locale)
			inputBinding.put("errorList", errorList)
		}		
		return inputBinding
	}
	
}
package script.workflowActivity
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger

import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TStateBean
import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.errors.ErrorData
import com.aurel.track.fieldType.runtime.base.WorkItemContext
import com.aurel.track.item.link.LinkedItemsStatusBL
import com.aurel.track.util.event.IEventHandler

public class ChangeChildrenStatusReverse implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(ChangeChildrenStatusReverse.class);
	/**
	 * Changes all child items' status from "fromStatusBean" to "toStatusBean"
	 * Could be used as workflow activity script,
	 * for example when the parent item's status is set back to a previous status
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		Integer itemID = workItemBean.getObjectID()
		LOGGER.debug(String.format("ChangeChildrenStatusReverse called for %s %d", workItemBean.getSynopsis(), itemID))
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		//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
		TStateBean fromStatusBean = StatusBL.loadByLabel("bereit", Locale.GERMAN)
		Integer fromStatusID = null
		if (fromStatusBean!=null) {
			fromStatusID = fromStatusBean.getObjectID()
		}
		TStateBean toStatusBean = StatusBL.loadByLabel("nicht bereit", Locale.GERMAN)
		Integer toStatusID = null
		if (toStatusBean!=null) {
			toStatusID = toStatusBean.getObjectID()
		}
		if (toStatusID!=null) {
			List<ErrorData> errorList = LinkedItemsStatusBL.changeStatusOfOpenChildren(itemID, linkTypeID, linkDirection, 
				fromStatusID, toStatusID, null, personBean, locale)		
			inputBinding.put("errorList", errorList)
		}
		return inputBinding
	}
	
}
package script.workflowActivity
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger

import com.aurel.track.admin.customize.category.filter.execute.loadItems.ItemListHierarchyBL
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
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.FieldsManagerRT
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.item.link.LinkedItemsStatusBL
import com.aurel.track.linkType.ILinkType.LINK_DIRECTION
import com.aurel.track.util.GeneralUtils
import com.aurel.track.util.event.IEventHandler

public class ChangeLinkedItemsStatus implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(ChangeLinkedItemsStatus.class);
	/**
	 * Changes the status of linked successor that are in status "fromStatusBean" to "toStatusBean"
	 * if all predecessors are in status "doneStatusBean"
	 * Could be used as workflow activity script,
	 * for example when the item reaches a certain status
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		Integer itemID = workItemBean.getObjectID()
		LOGGER.debug(String.format("ChangeLinkedItemsStatus called for %s %d", workItemBean.getSynopsis(), itemID))
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		List<ErrorData> errorList = null;
		//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
		TStateBean fromStatusBean = StatusBL.loadByLabel("nicht bereit", Locale.GERMAN)
		Integer fromStatusID = null
		if (fromStatusBean!=null) {
			fromStatusID = fromStatusBean.getObjectID()
		}
		TStateBean toStatusBean = StatusBL.loadByLabel("bereit", Locale.GERMAN)
		Integer toStatusID = null
		if (toStatusBean!=null) {
			toStatusID = toStatusBean.getObjectID()
		}
		TStateBean doneStatusBean = StatusBL.loadByLabel("erledigt", Locale.GERMAN)
		Integer doneStatusID = null;
		if (doneStatusBean!=null) {
			doneStatusID = doneStatusBean.getObjectID();
		}
		if (toStatusID!=null) {
			errorList = LinkedItemsStatusBL.changeLinkedItemsStatus(itemID,
				linkTypeID, linkDirection, fromStatusID, toStatusID, doneStatusID, personBean, locale)
		}
		inputBinding.put("errorList", errorList)
		return inputBinding
	}
	
}
package script.workflowActivity
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger

import com.aurel.track.admin.customize.category.filter.execute.loadItems.ItemListHierarchyBL
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
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.WorkItemContext
import com.aurel.track.item.ItemBL
import com.aurel.track.item.link.ItemLinkBL
import com.aurel.track.item.link.LinkedItemsStatusBL
import com.aurel.track.linkType.ILinkType.LINK_DIRECTION
import com.aurel.track.util.GeneralUtils
import com.aurel.track.util.event.IEventHandler

public class ChangeLinkedItemsStatusReverse implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(ChangeLinkedItemsStatusReverse.class);
	/**
	 * Changes the status of linked successor that are in status "fromStatusBean" to "toStatusBean"
	 * Could be used as workflow activity script,
	 * for example when the item's status is set back to a previous status
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		Integer itemID = workItemBean.getObjectID()
		LOGGER.debug(String.format("ChangeLinkedItemsStatusReverse called for %s %d", workItemBean.getSynopsis(), itemID))
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		List<ErrorData> errorList = null;
		//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
		TStateBean fromStatusBean = StatusBL.loadByLabel("bereit", Locale.GERMAN)
		Integer fromStatusID = null
		if (fromStatusBean!=null) {
			fromStatusID = fromStatusBean.getObjectID()
		}
		TStateBean toStatusBean = StatusBL.loadByLabel("nicht bereit", Locale.GERMAN)
		Integer toStatusID = null
		if (toStatusBean!=null) {
			toStatusID = toStatusBean.getObjectID()
		}
		if (toStatusID!=null) {
			errorList = LinkedItemsStatusBL.changeLinkedItemsStatus(itemID,
				linkTypeID, linkDirection, fromStatusID, toStatusID, null, personBean, locale)
		}
		inputBinding.put("errorList", errorList)
		return inputBinding
	}
}
package script.workflowActivity
import com.aurel.track.admin.customize.lists.systemOption.ItemTypeBL
import com.aurel.track.admin.customize.lists.systemOption.ItemTypeFlag
import com.aurel.track.admin.customize.lists.systemOption.SeverityBL
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.beans.TLinkTypeBean
import com.aurel.track.beans.TListTypeBean
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TSeverityBean
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.constants.SystemFields
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.item.link.ItemLinkConfigBL
import com.aurel.track.linkType.LinkTypeBL
import com.aurel.track.resources.LocalizeUtil
import com.aurel.track.util.event.IEventHandler

public class ChangeParentItemType implements IEventHandler {

	/**
	 * Changes the parent item type from Task to Task-Block
	 * Could be used as workflow activity script,
	 * for example when adding a new child to a parent item
	 */
	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<>()
		Integer parentID = workItemBean.getSuperiorworkitem()
		if (parentID!=null) {
			TWorkItemBean parentItem = ItemBL.loadWorkItemSystemAttributes(parentID)
			if (parentItem!=null && ItemTypeBL.isOfFlag(parentItem.getListTypeID(), ItemTypeFlag.TASK.getFlag())) {
				WorkItemContext parentContext = ItemBL.editWorkItem(parentID, personBean, locale, false)
				Integer newItemTypeID = null
				//this value above can be set directly (ID read from db), then comment the next 3 lines 
				List<TListTypeBean> newItemTypeList = ItemTypeBL.loadByLabel("Aufgabenblock", Locale.GERMAN)
				if (newItemTypeList!=null && !newItemTypeList.isEmpty()) {
					newItemTypeID = newItemTypeList.get(0).getObjectID()
				}
				if (newItemTypeID!=null && !newItemTypeID.equals(parentItem.getListTypeID())) {
					parentItem = parentContext.getWorkItemBean()
					parentItem.setListTypeID(newItemTypeID);
					ItemBL.saveWorkItem(parentContext, errorList, true, null)
				}
			}
		}
		inputBinding.put("errorList", errorList)
		return inputBinding
	}
}
package script.workflowActivity
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger

import com.aurel.track.admin.customize.category.filter.execute.loadItems.ItemListHierarchyBL
import com.aurel.track.admin.customize.lists.systemOption.SeverityBL
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.beans.TLinkTypeBean
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TSeverityBean
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.constants.SystemFields
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.item.link.ItemLinkConfigBL
import com.aurel.track.linkType.LinkTypeBL
import com.aurel.track.resources.LocalizeUtil
import com.aurel.track.util.event.IEventHandler

public class ChangeParentStatus implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(ChangeParentStatus.class);
	/**
	 * Changes the parent item's status to their children's status,
	 * when all children have the same status
	 * Could be used as workflow activity script,
	 * for example when changing a child item' status
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		Integer itemID = workItemBean.getObjectID()
		LOGGER.debug(String.format("ChangeParentStatus called for %s %d", workItemBean.getSynopsis(), itemID))
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		List<ErrorData> errorList = new ArrayList<>()
		Integer parentID = workItemBean.getSuperiorworkitem()
		if (parentID!=null) {
			List<TWorkItemBean> openChildren = ItemListHierarchyBL.getChildren(parentID, personBean.getObjectID())
			Integer statusID = workItemBean.getStateID()
			LOGGER.debug(String.format("Status for child %d: %s", itemID,
				LookupContainer.getLocalizedLabelBeanLabel(SystemFields.STATE, statusID, locale)))
			if (openChildren!=null && !openChildren.isEmpty()) {
				boolean sameStatus = true
				for (TWorkItemBean childItemBean in openChildren) {
					Integer childItemID = childItemBean.getObjectID()
					Integer childStatusID = childItemBean.getStateID()
					if (!statusID.equals(childStatusID) /*&& !itemID.equals(childItemID)*/) {
						sameStatus = false
						LOGGER.debug(String.format("Different status for sibling %d: %s", childItemID,
							LookupContainer.getLocalizedLabelBeanLabel(SystemFields.STATE, childStatusID, locale)))
					}
				}
				if (sameStatus) {
					//System.out.println("Same status for all children: " + LookupContainer.getLocalizedLabelBeanLabel(SystemFields.STATE, statusID, locale))
					WorkItemContext parentContext = ItemBL.editWorkItem(parentID, personBean, locale, false)
					TWorkItemBean parentItem = parentContext.getWorkItemBean();
					Integer parentStatusID = parentItem.getStateID();
					if (!statusID.equals(parentStatusID)) {
						parentItem.setStateID(statusID);
						ItemBL.saveWorkItem(parentContext, errorList, true, null)
						LOGGER.debug(String.format("Status for parent %d %s set to %s", parentItem.getObjectID(), parentItem.getSynopsis(),
							LookupContainer.getLocalizedLabelBeanLabel(SystemFields.STATE, statusID, locale)))
					}
				}
			}
		}
		inputBinding.put("errorList", errorList)
		return inputBinding
	}
}
package script.workflowActivity
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger

import com.aurel.track.admin.customize.category.filter.execute.loadItems.ItemListHierarchyBL
import com.aurel.track.admin.customize.lists.systemOption.SeverityBL
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.beans.TLinkTypeBean
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TSeverityBean
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.constants.SystemFields
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.item.link.ItemLinkConfigBL
import com.aurel.track.linkType.LinkTypeBL
import com.aurel.track.resources.LocalizeUtil
import com.aurel.track.util.event.IEventHandler

public class ChangeParentStatusToChildStatus implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(ChangeParentStatusToChildStatus.class);
	/**
	 * Changes the parent item's status to this child's status,
	 * independently of the other children's status
	 * Could be used as workflow activity script
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		Integer itemID = workItemBean.getObjectID()
		LOGGER.debug(String.format("ChangeParentStatusToChildStatus called for %s %d", workItemBean.getSynopsis(), itemID))
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		List<ErrorData> errorList = new ArrayList<>()
		Integer parentID = workItemBean.getSuperiorworkitem()
		if (parentID!=null) {
			Integer statusID = workItemBean.getStateID()
			WorkItemContext parentContext = ItemBL.editWorkItem(parentID, personBean, locale, false)
			TWorkItemBean parentItem = parentContext.getWorkItemBean();
			Integer parentStatusID = parentItem.getStateID();
			if (!statusID.equals(parentStatusID)) {
				parentItem.setStateID(statusID);
				ItemBL.saveWorkItem(parentContext, errorList, true, null)
				LOGGER.debug(String.format("Status for parent %d %s set to %s", parentItem.getObjectID(), parentItem.getSynopsis(),
					 LookupContainer.getLocalizedLabelBeanLabel(SystemFields.STATE, statusID, locale)))
			}
		}
		inputBinding.put("errorList", errorList)
		return inputBinding
	}
}
package script.workflowActivity
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger

import com.aurel.track.admin.customize.category.filter.execute.loadItems.ItemListHierarchyBL
import com.aurel.track.admin.customize.lists.systemOption.SeverityBL
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.beans.TLinkTypeBean
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TSeverityBean
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.constants.SystemFields
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.item.link.ItemLinkConfigBL
import com.aurel.track.linkType.LinkTypeBL
import com.aurel.track.resources.LocalizeUtil
import com.aurel.track.util.event.IEventHandler

public class ChangeParentStatusToChildStatusExceptSiblingStatuses implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(ChangeParentStatusToChildStatusExceptSiblingStatuses.class);
	/**
	 * Sets the parent status to the actually edited child's status unless the child has a sibling 
	 * (i.e. parent has another child) having an exception status specified in getExceptStatusIDs()
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		Integer itemID = workItemBean.getObjectID()
		LOGGER.debug(String.format("ChangeParentStatusToChildStatusExceptSiblingStatuses called for %s %d", workItemBean.getSynopsis(), itemID))
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		List<ErrorData> errorList = new ArrayList<>()
		Integer parentID = workItemBean.getSuperiorworkitem()
		if (parentID!=null) {
			List<TWorkItemBean> openChildren = ItemListHierarchyBL.getChildren(parentID, personBean.getObjectID())
			Integer statusID = workItemBean.getStateID()
			LOGGER.debug(String.format("Status for child %d: %s", itemID,
				LookupContainer.getLocalizedLabelBeanLabel(SystemFields.STATE, statusID, locale)))
			if (openChildren!=null && !openChildren.isEmpty()) {
				Set<Integer> exceptStatusIDs = getExceptStatusIDs();
				boolean exceptStatusExists = false
				for (TWorkItemBean childItemBean in openChildren) { 
					Integer childStatusID = childItemBean.getStateID()
					if (exceptStatusIDs.contains(childStatusID)) {
						exceptStatusExists = true
						LOGGER.debug(String.format("Except status for sibling %d: %s", childItemBean.getObjectID(),
							LookupContainer.getLocalizedLabelBeanLabel(SystemFields.STATE, childStatusID, locale)))
						break;
					}
				}
				if (!exceptStatusExists) {
					//System.out.println("No except status among children")
					WorkItemContext parentContext = ItemBL.editWorkItem(parentID, personBean, locale, false)
					TWorkItemBean parentItem = parentContext.getWorkItemBean();
					Integer parentStatusID = parentItem.getStateID();
					if (!statusID.equals(parentStatusID)) {
						parentItem.setStateID(statusID);
						ItemBL.saveWorkItem(parentContext, errorList, true, null)
						LOGGER.debug(String.format("Status for parent %d %s set to %s", parentItem.getObjectID(), parentItem.getSynopsis(),
							LookupContainer.getLocalizedLabelBeanLabel(SystemFields.STATE, statusID, locale)))
					}
				}
			}
		}
		inputBinding.put("errorList", errorList)
		return inputBinding
	}
	
	/**
	 * Gets the statuses to block the transition of the parent status to the child status
	 * if any sibling of child item have any of exception statuses
	 * @return
	 */
	private static Set<Integer> getExceptStatusIDs() {
		Set<Integer> exceptStatusIDs = new HashSet()
		//change here the actual
		TStateBean processiongStatusBean = StatusBL.loadByLabel("in Bearbeitung", Locale.GERMAN)
		if (processiongStatusBean!=null) {
			exceptStatusIDs.add(processiongStatusBean.getObjectID())
		}
		TStateBean notReadyStatusBean = StatusBL.loadByLabel("nicht bereit", Locale.GERMAN)
		if (notReadyStatusBean!=null) {
			exceptStatusIDs.add(notReadyStatusBean.getObjectID())
		}
		return exceptStatusIDs;
	}
	
	
}
package script.workflowActivity



import java.util.LinkedList
import java.util.List
import java.util.Locale
import java.util.Map

import com.aurel.track.beans.TLinkTypeBean
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.errors.ErrorData
import com.aurel.track.fieldType.runtime.base.WorkItemContext
import com.aurel.track.item.ItemBL
import com.aurel.track.item.link.ItemLinkConfigBL
import com.aurel.track.linkType.LinkTypeBL
import com.aurel.track.util.event.IEventHandler

public class CopyItem implements IEventHandler {

	/**
	 * Copies an item and creates a link between the original item and copied item
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get(
			"workItemContext")
		TWorkItemBean workItemBean = workItemContext.getWorkItemBean()
		Integer copiedFromItemID = workItemBean.getObjectID()
		TPersonBean personBean = (TPersonBean)inputBinding.get("user")
		Locale locale = (Locale)inputBinding.get("locale")
		List<ErrorData> errorList = new LinkedList<ErrorData>()
		//create a copy of an item
		WorkItemContext copyContext =  ItemBL.editCopyWorkItem(copiedFromItemID, personBean, locale)
		TWorkItemBean workItemBeanCopy = copyContext.getWorkItemBean()
		//change the copied item as needed
		workItemBeanCopy.setSynopsis("(Copy) " + workItemBeanCopy.getSynopsis())
		//save the copied item in db
		Integer copiedItemID = ItemBL.copyWorkItem(copyContext, 
			errorList, false)
		//look up the linktype ID in Link types config, ID column
		Integer linkTypeID = 1001
		// 1=Unidirectional outward and bidirectional links, 
		// 2=Unidirectional inward (MsProject)
		Integer linkDirection = 1	
		List<ErrorData> linkErrors = ItemLinkConfigBL.saveItemLink(
			copiedFromItemID, copiedItemID, linkTypeID+"-" + linkDirection, 
			null, null, personBean, locale, null, workItemContext)
		if (linkErrors!=null) {
			errorList.addAll(linkErrors)
		}
		inputBinding.put("errorList", errorList)
		return inputBinding
	}
}
package script.workflowActivity
import com.aurel.track.admin.customize.scripting.BINDING_PARAMS
import com.aurel.track.admin.customize.scripting.GroovyLogger;
import com.aurel.track.beans.TWorkItemBean;
import com.aurel.track.fieldType.runtime.base.WorkItemContext;


public class EmailSender {

	/**
	 * Sets a specific item attribute to the name of the email sender
	 * Just an example workflow script
	 * 
	 * @return
	 */
	public Map handleEvent(Map inputBinding) {
		TWorkItemBean workItemBean =
				(TWorkItemBean)inputBinding.get(BINDING_PARAMS.ITEM);
		WorkItemContext workItemContext =
				(WorkItemContext)inputBinding.get(BINDING_PARAMS.WORKITEM_CONTEXT);
		String subject = (String)inputBinding.get(BINDING_PARAMS.EMAIL_SUBJECT);
		if (subject==null) {
			return inputBinding;
		}
		String senderName = (String)inputBinding.get(
				BINDING_PARAMS.EMAIL_FROM_NAME);
		GroovyLogger.LOGGER.debug("EmailSender: " + senderName);
		workItemBean.setAttribute(1152, senderName);
		return inputBinding;
	}
}
package script.workflowActivity

import java.util.LinkedList
import java.util.List
import java.util.Locale
import java.util.Map

import com.aurel.track.admin.customize.category.filter.execute.loadItems.ItemListHierarchyBL
import com.aurel.track.admin.customize.lists.systemOption.ItemTypeBL
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
import com.aurel.track.beans.TLinkTypeBean
import com.aurel.track.beans.TListTypeBean
import com.aurel.track.beans.TPersonBean
import com.aurel.track.beans.TStateBean
import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.errors.ErrorData
import com.aurel.track.fieldType.runtime.base.FieldsManagerRT
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.item.link.ItemLinkConfigBL
import com.aurel.track.linkType.LinkTypeBL
import com.aurel.track.util.event.IEventHandler

public class ReopenClosedChildren implements IEventHandler {

	/**
	 * Sets the closed children of type Requirement to status Assessing
	 */
	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 LinkedList<ErrorData>()
		List<TWorkItemBean> children = ItemListHierarchyBL.getChildren(itemID, personBean.getObjectID())
		if (children!=null && !children.isEmpty()) {
			Integer requirementItemTypeID = null
			List<TListTypeBean> itemTypes = ItemTypeBL.loadByLabel("Requirement")
			if (itemTypes!=null && !itemTypes.isEmpty()) {
				TListTypeBean itemTypeBean = itemTypes.get(0)
				requirementItemTypeID = itemTypeBean.getObjectID()
			} else {
				System.out.println("No item type found")
			}
			Integer reviewState = null
			List<TStateBean> statusBeans = StatusBL.loadByLabel("Assessing")
			if (statusBeans!=null && !statusBeans.isEmpty()) {
				TStateBean statusBean = statusBeans.get(0)
				reviewState = statusBean.getObjectID()
			} else {
				System.out.println("No target status found")
			}
			List<TStateBean> closedStateBeans = StatusBL.loadClosedStates()
			List<Integer> closedStateIDs = new ArrayList()
			if (closedStateBeans!=null && !closedStateBeans.isEmpty()) {
				for (TStateBean stateBean : closedStateBeans) {
					closedStateIDs.add(stateBean.getObjectID())
				}
			}
			if (requirementItemTypeID!=null && reviewState!=null && !closedStateIDs.isEmpty()) {
				for (TWorkItemBean childBean : children) {
					if (requirementItemTypeID.equals(childBean.getListTypeID()) && closedStateIDs.contains(childBean.getStateID())) {
						WorkItemContext childContext = ItemBL.editWorkItem(
							childBean.getObjectID(), personBean, locale, false)
						TWorkItemBean childItem = childContext.getWorkItemBean()
						childItem.setStateID(reviewState)
						//ItemBL.saveWorkItem(childContext, errorList, false, null)  cann't be used (to avoid infinite recursion if called with validate by closePossibleValidate())
						FieldsManagerRT.saveWithoutValidate(childContext, false, false, errorList, false, true);
					}
				}
			}
		}
		inputBinding.put("errorList", errorList)
		return inputBinding
	}
}
package script.workflowActivity

import com.aurel.track.accessControl.AccessControlBL
import com.aurel.track.admin.customize.scripting.BINDING_PARAMS
import com.aurel.track.admin.customize.lists.systemOption.StatusBL
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.WorkItemContext
import com.aurel.track.item.link.LinkedItemsStatusBL
import com.aurel.track.util.event.IEventHandler
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.aurel.track.fieldType.runtime.base.LookupContainer
import com.aurel.track.fieldType.constants.SystemFields
import com.aurel.track.item.ItemBL
import com.aurel.track.item.link.ItemLinkBL

public class SetChildStatusByParentStatus implements IEventHandler {
	private static final Logger LOGGER = LogManager.getLogger(SetChildStatusByParentStatus.class);
	/**
	 * Changes the items' status to parent's status if the parent status is within the configured ones and the child has no predecessor
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		WorkItemContext workItemContext = (WorkItemContext)inputBinding.get(BINDING_PARAMS.WORKITEM_CONTEXT)
		TWorkItemBean workItemBean = (TWorkItemBean)inputBinding.get(BINDING_PARAMS.ITEM)
		TPersonBean personBean = (TPersonBean)inputBinding.get(BINDING_PARAMS.USER)
		Locale locale = (Locale)inputBinding.get(BINDING_PARAMS.LOCALE)
		Integer itemID = workItemBean.getObjectID()
		Integer parentID = workItemBean.getSuperiorworkitem()
		if (parentID!=null) {
			LOGGER.debug(String.format("SetChildStatusByParentSttaus called for %s", workItemBean.getSynopsis()))
			TWorkItemBean parentItem = ItemBL.loadWorkItemSystemAttributes(parentID)
			Integer parentStatusID = parentItem.getStateID()
			LOGGER.debug(String.format("Parent status is %d", parentStatusID))
			//look up the linktype ID in Link types config, ID column
			Integer linkTypeID = 4
	        List<ErrorData> errorList = new ArrayList<>()
			// 1=Unidirectional outward and bidirectional links, 
			// 2=Unidirectional inward (MsProject)
			Integer linkDirection = 2
			Set<Integer> parentStatusesToTakeOver = new HashSet();
			//TStateBean fromStatusBean = StatusBL.loadByLabel("nicht bereit", Locale.GERMAN)
			TStateBean readyStatusBean = StatusBL.loadByLabel("bereit", Locale.GERMAN)
			Integer readyStatusID = null
			if (readyStatusBean !=null) {
				readyStatusID = readyStatusBean .getObjectID()
			}
			parentStatusesToTakeOver.add(readyStatusID)
			TStateBean processingStatusBean = StatusBL.loadByLabel("in Bearbeitung", Locale.GERMAN)
			Integer processingStatusID = null
			if (processingStatusBean !=null) {
				processingStatusID = processingStatusBean.getObjectID();
			}
			parentStatusesToTakeOver.add(processingStatusID)
			LOGGER.debug(String.format("Child statuses to take into account: %s", parentStatusesToTakeOver))
			if (parentStatusesToTakeOver.contains(parentStatusID)) {
				SortedMap<Integer, TWorkItemLinkBean> workItemsLinksMap = workItemContext.getWorkItemsLinksMap();
				if (workItemsLinksMap==null || workItemsLinksMap.isEmpty()) {
					LOGGER.debug(String.format("No predecessor found for %s",  workItemBean.getSynopsis()))
					workItemBean.setStateID(parentStatusID);
			    } else {
					for (workItemsLink in workItemsLinksMap.values()) {
						if (workItemsLink.getLinkType().equals(linkTypeID) && workItemsLink.getLinkDirection().equals(linkDirection)) {
							LOGGER.debug(String.format("Predecessor found for '%s' from %d", workItemBean.getSynopsis(), workItemsLink.getLinkPred()))
							break
						}
					}
				}
			}	
		}
		return inputBinding
	}
	
}
package script.workflowActivity

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
import com.aurel.track.fieldType.constants.SystemFields
import com.aurel.track.fieldType.runtime.base.WorkItemContext
import com.aurel.track.resourceCalendar.itemDuration.ItemDurationBL

public class SetEndDate {
	
	/**
	 * Sets the end date to the actual date, and computes also the duration
	 * Useful for example for workflow transition to status "closed" 
	 * @param inputBinding
	 * @return
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		TFieldBean dateField = FieldBL.loadByName("EndDate");
		if (dateField!=null) {
			Integer fieldID = dateField.getObjectID();
			WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext");
			workItemContext.getPresentFieldIDs().add(fieldID);
			TWorkItemBean workItemBean = inputBinding.get("item");
			workItemBean.setAttribute(fieldID, new Date());
			//recalculate duration
			boolean startWithTime = ItemDurationBL.isWithTime(SystemFields.STARTDATE, workItemBean.getProjectID(), workItemBean.getListTypeID());
			boolean endWithTime = ItemDurationBL.isWithTime(SystemFields.ENDDATE, workItemBean.getProjectID(), workItemBean.getListTypeID());
			Double duration = ItemDurationBL.getDuration(workItemBean.getStartDate(), startWithTime, workItemBean.getEndDate(), endWithTime,
				workItemBean.getResponsibleID());
			workItemBean.setDuration(duration);
		}
		return inputBinding;
	}
}
package script.workflowActivity

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
import com.aurel.track.fieldType.runtime.base.WorkItemContext

public class SetFieldValue {
	
	/**
	 * Sets the ImplementationDate custom date attribute to the actual date
	 * Useful for example for workflow transition to status "implemented" 
	 * @param inputBinding
	 * @return
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		TFieldBean dateField = FieldBL.loadByName("ImplementationDate");
		if (dateField!=null) {
			Integer fieldID = dateField.getObjectID();
			WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext");
			workItemContext.getPresentFieldIDs().add(fieldID);
			TWorkItemBean workItemBean = inputBinding.get("item");
			workItemBean.setAttribute(fieldID, new Date());
		}
		return inputBinding;
	}
}
package script.workflowActivity

import com.aurel.track.admin.customize.treeConfig.field.FieldBL
import com.aurel.track.beans.TFieldBean
import com.aurel.track.beans.TWorkItemBean
import com.aurel.track.fieldType.constants.SystemFields
import com.aurel.track.fieldType.runtime.base.WorkItemContext
import com.aurel.track.resourceCalendar.itemDuration.ItemDurationBL

public class SetStartDate {
	/**
	 * Sets the start date to the actual date, and computes also the end date if duration is set
	 * Useful for example for workflow transition to status "processing" 
	 * @param inputBinding
	 * @return
	 */
	public Map<String, Object> handleEvent(Map<String, Object> inputBinding) {
		TFieldBean dateField = FieldBL.loadByName("StartDate");
		if (dateField!=null) {
			Integer fieldID = dateField.getObjectID();
			WorkItemContext workItemContext = (WorkItemContext)inputBinding.get("workItemContext");
			workItemContext.getPresentFieldIDs().add(fieldID);
			TWorkItemBean workItemBean = inputBinding.get("item");
			workItemBean.setAttribute(fieldID, new Date());
			Date startDate = workItemBean.getStartDate();
			if (startDate!=null && workItemBean.getDuration()!=null) {
				//recalculate endDate
				boolean startWithTime = ItemDurationBL.isWithTime(SystemFields.STARTDATE, workItemBean.getProjectID(), workItemBean.getListTypeID());
				Date endDate = ItemDurationBL.getEndDate(startDate, startWithTime, workItemBean.getDuration(), workItemBean.getResponsibleID());
				if (endDate!=null) {
					workItemBean.setEndDate(endDate);
				}
			}
		}
		return inputBinding;
	}
}