# BPM Extension Interface

Version: 1.0 | Release Date: 30/9/2019

# What can I do?

  1. Extend the source and relationship of participants
  2. Extend the parameters used in the Formula
  3. Extend the parameters used in Condition
  4. Add action before submit
  5. Add action after ChangeNote approved
  6. Monitor all events in the workflow

# BpmHandler

public interface BpmHandler {

	/*return key,mess */
	public Map<String, String> extendDynamicPatorSource(String moduleName);

	public Map<String, String> extendDynamicPatorShip(String moduleName);

	/* return target user id*/
	public Set<Long> getExtendPatorSourceValue(String moduleName, SqlEntity data, String srcField);

	public Set<Long> getExtendPatorShipValue(String moduleName, SqlEntity data, String ship, long uid, long empId);

	public Set<Long> getExtendPatorShipValue(String moduleName, SqlEntity data, String ship, long uid, long empId, long reportingLineId);

	/*exclude lookup=user,employee field which default as source*/
	public Set<String> excludeDynamicPatorSource(String moduleName);

	/*return entity identify for bpm */
	public String getEntityIdentify(String moduleName, SqlEntity src);

	// such as ce01 business rule
	public List<DynamicField> extendDynamicField(String moduleName);

	public List<DynamicField> dynamicFieldCurrentValue(String moduleName, SqlEntity data);

	public boolean changeNoteApproved(String moduleName, SqlEntity origin, SqlEntity changeNote, String changeNoteCode);

	// return empty string means ok
	public String checkBeforeSubmit(String moduleName, SqlEntity data);
}

# 1. Extend the source of Participants

bpm1 extendDynamicPatorSource

@Override
public Map<String, String> extendDynamicPatorSource(String moduleName) {
	Map<String, String> extendSource = new HashMap<String, String>();
	if ("employee".equals(moduleName) && CawLib.isApDebug()) {
		extendSource.put(e_source, "wf.extendA");
	}
	return extendSource;
}

getExtendPatorSourceValue

@Override
public Set<Long> getExtendPatorSourceValue(String moduleName, SqlEntity data, String srcField) {
	Set<Long> targetUser = new HashSet<Long>();
	if ("employee".equals(moduleName) && data.getModuleType().equals(moduleName) && CawLib.isApDebug()) {
		if (e_source.equals(srcField)) {
			Long publiserId = data.getMainData().getLong(1, "createUid");
			targetUser.add(publiserId);
		}
	}
	return targetUser;
}

# 2. Extend the relationship of Participants

bpm2

extendDynamicPatorShip

@Override
public Map<String, String> extendDynamicPatorShip(String moduleName) {
	Map<String, String> extendSource = new HashMap<String, String>();
	if ("employee".equals(moduleName) && CawLib.isApDebug()) {
		extendSource.put(e_ship, "wf.extendShip");
	}
	return extendSource;
}

getExtendPatorShipValue

// Keep this method for backward compatibility
@Override
@Deprecated
public Set<Long> getExtendPatorShipValue(String moduleName, SqlEntity data, String ship, long uid, long empId) {
	Set<Long> targetUser = new HashSet<Long>();
	if ("employee".equals(moduleName) && data.getModuleType().equals(moduleName) && CawLib.isApDebug()) {
		if (e_ship.equals(ship)) {
			if (uid > 0) {
				targetUser.add(uid);
			} else if (empId > 0) {
				// found user id by employee id
			}
		}
	}
	return targetUser;
}

new method contains a new parameter reportingLineId, If you implement both methods at the same time, only new methods will be called

public Set<Long> getExtendPatorShipValue(String moduleName, SqlEntity data, String ship, long uid, long empId, long reportingLineId);

# 3. Extend the parameters used in the Condition

bpm3

# 4. Extend the parameters used in the Formula

bpm4

extendDynamicField

@Override
public List<DynamicField> extendDynamicField(String moduleName) {
	List<DynamicField> ef = new ArrayList<DynamicField>();
	if ("employee".equals(moduleName) && CawLib.isApDebug()) {
		DynamicField f1 = new DynamicField("fA", "code", "messA");
		DynamicField f2 = new DynamicField("fB", "code", "messB");

		ef.add(f1);
		ef.add(f2);
	}
	return ef;
}

dynamicFieldCurrentValue

@Override
public List<DynamicField> dynamicFieldCurrentValue(String moduleName, SqlEntity data) {
	List<DynamicField> ef = new ArrayList<DynamicField>();
	if ("employee".equals(moduleName) && CawLib.isApDebug()) {
		DynamicField f1 = new DynamicField("fA", "code", "messA");
		DynamicField f2 = new DynamicField("fB", "code", "messB");
		f1.setValue("AAAAA");
		f2.setValue("BBBBB");

		ef.add(f1);
		ef.add(f2);
	}
	return ef;
}

# 5. Add action before workflow submit

If the returned result is not an empty string, the submit process is aborted and the returned result is displayed to the user.

@Override
public String checkBeforeSubmit(String moduleName, SqlEntity data) {
	if ("employee2".equals(moduleName) && CawLib.isApDebug()) {
		return CawGlobal.getMess("wf.actionFailInfo2");
	}
	return super.checkBeforeSubmit(moduleName, data);
}

# 6. Add action after ChangeNote approved

After the changenote is approved, we will use the changenote to overwrite the original record. This method will be called before the overwrite, and the return result indicates whether the overwrite process will be processed after this method.

@Override
public boolean changeNoteApproved(String moduleName, SqlEntity origin, SqlEntity changeNote, String changeNoteCode) {
	return false;
}

# Bpm Event Listener

On the BPM interface, you can configure different response actions according to different events. If you want to capture these events at the code level and perform corresponding operations, please see below.

@CawEventListener(eventTopic = WfTopic.BpmEvent)
public class AncmBpmEventListener extends CawListenerAdapter {

	@Override
	public void callEvent(Object param) {
		if (param == null || !(param instanceof WfPublishPara)) {
			return;
		}
		WfPublishPara msg = (WfPublishPara) param;
		if (!"ancm".equals(msg.getApvModule()) || !(WfInsState.ENDED).equals(msg.getWfInsState())) {
			return;
		}

		long ancmId = msg.getApvRecordId();
		CheckMsg ckmsg = AncmUtil.publishAncmBpm(ancmId);
		if (ckmsg != null) {
			CawLog.error(ckmsg.getInfo());
		}
	}
}