Context

This is the form to capture the grid data.

On submission of this form, we would like to start a process instance for each of the rows from this grid.

We would like to start a process instance of the process definition "travel_approver_process".

We will need to pick up the grid data by matching the current batch record ID in gda_batch and list down records from gda_travel.

Sample SQL
SELECT * FROM app_fd_gda_travel WHERE c_batch = '#form.gda_batch.id#'

Solution

In the batch form itself, we can make use of "Post Form Submission Processing" to capture event of "Data Creation" or "Both data creation and update", whichever suits your own use case, to execute bean shell Java code to achieve this.

Bean shell Java code to iterate through grid data and start a process instance for each of the rows.

import org.joget.workflow.model.service.WorkflowManager;
import org.joget.apps.app.service.AppUtil;
import org.joget.apps.app.service.AppService;
import org.joget.workflow.model.WorkflowAssignment;
import org.joget.workflow.util.WorkflowUtil;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.joget.workflow.model.WorkflowProcess;
import org.joget.workflow.model.WorkflowProcessResult;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.joget.commons.util.LogUtil;

//define process to start
String processDefKey = "travel_approver_process";

//utility bean
WorkflowManager workflowManager = (WorkflowManager) AppUtil.getApplicationContext().getBean("workflowManager");
AppService appService = (AppService) AppUtil.getApplicationContext().getBean("appService");
 
//get processDefId
WorkflowProcess processDef = appService.getWorkflowProcessForApp(appDef.getId(), appDef.getVersion().toString(), processDefKey);
String processDefId = processDef.getId();

//get foreign key
String batchId = "#form.gda_batch.id#";

Connection con = null;

try {
    // retrieve connection from the default datasource
    DataSource ds = (DataSource)AppUtil.getApplicationContext().getBean("setupDataSource");
    con = ds.getConnection();
  
    // execute SQL query
    if(!con.isClosed()) {
        PreparedStatement stmt = con.prepareStatement("SELECT * FROM app_fd_gda_travel WHERE c_batch = ?");
        stmt.setObject(1, batchId);
        ResultSet rs = stmt.executeQuery();
        while (rs.next()) {
            LogUtil.info(appDef.toString(), "Processing Batch " + batchId + " - Record: " + rs.getObject("id"));
		    Map variables = new HashMap();
		    //variables.put("batch", batchId);
		    WorkflowProcessResult result = workflowManager.processStart(processDefId, null, variables, "admin", rs.getObject("id"), false);
            LogUtil.info(appDef.toString(), "Processing Batch " + batchId + " - Record: " + rs.getObject("id") + " - Status: " + result.getProcess().getInstanceId());
        }
    }
} catch(Exception e) {
    LogUtil.error(appDef.toString(), e, "Error in creating approval process for batch " + batchId);
} finally {
    //always close the connection after used
    try {
        if(con != null) {
            con.close();
        }
    } catch(SQLException e) {/* ignored */}
}


We make use of LogUtil.info in the code. In the server log, we will see printout such as below:-


INFO 25 Jan 2021 12:18:43 {id=gridDataApproval, version=1, published=true} - Processing Batch 6f0abea4-bb36-4064-96d0-7c90ea9daed6 - Record: 1841e8e6-71b3-4388-84f8-0d39da7ee8ee
INFO 25 Jan 2021 12:18:43 org.joget.workflow.shark.WorkflowAssignmentManager - [processId=3639_gridDataApproval_travel_approver_process, processDefId=gridDataApproval#1#travel_approver_process, participantId=travel_approver, next user=[admin]]
INFO 25 Jan 2021 12:18:43 {id=gridDataApproval, version=1, published=true} - Processing Batch 6f0abea4-bb36-4064-96d0-7c90ea9daed6 - Record: 1841e8e6-71b3-4388-84f8-0d39da7ee8ee - Status: 3639_gridDataApproval_travel_approver_process
INFO 25 Jan 2021 12:18:43 {id=gridDataApproval, version=1, published=true} - Processing Batch 6f0abea4-bb36-4064-96d0-7c90ea9daed6 - Record: ba92fc7a-e477-431a-ba4e-8fe8e70cbf8b
INFO 25 Jan 2021 12:18:43 org.joget.workflow.shark.WorkflowAssignmentManager - [processId=3640_gridDataApproval_travel_approver_process, processDefId=gridDataApproval#1#travel_approver_process, participantId=travel_approver, next user=[admin]]
INFO 25 Jan 2021 12:18:43 {id=gridDataApproval, version=1, published=true} - Processing Batch 6f0abea4-bb36-4064-96d0-7c90ea9daed6 - Record: ba92fc7a-e477-431a-ba4e-8fe8e70cbf8b - Status: 3640_gridDataApproval_travel_approver_process

Once tested to be working, you may consider commenting them out to minimize unnecessary printout to the server log.

Sample App

You may refer to the sample app that is used in this article.

Additional note - The process in this app is generated and uses Process Enhancement Plugin DX but this is not mandatory/needed for the purpose of this article.

APP_gridDataApproval-1-20210125123233.jwa

  • No labels