/**
* Copyright (c) 2017 Avant-Port All Rights Reserved.
*/
package com.avp.mem.njpb.config;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* 初始化Activiti配置
* * @author Amber
*/
@Component
public class ActivitiInitConfig {
protected static final Logger LOGGER = LoggerFactory.getLogger(ActivitiInitConfig.class);
@Autowired
protected RepositoryService repositoryService;
@PostConstruct
public void init() {
initProcessDefinitions();
initProcess();
}
/**
* 为了让Activiti引擎知道这个流程,我们必须先进行“发布”。
* 发布意味着引擎会把BPMN 2.0 xml解析成可以执行的东西, “发布包”中的所有流程定义都会添加到数据库中。
* 这样,当引擎重启时,它依然可以获得“已发布”的流程。
*/
protected void initProcessDefinitions() {
String deploymentName = "workorder processes";
List deploymentList = repositoryService.createDeploymentQuery().deploymentName(deploymentName).list();
if (deploymentList == null || deploymentList.isEmpty()) {
Deployment deployment = repositoryService.createDeployment()
.name(deploymentName)
.addClasspathResource("diagrams/workorder/workorder.bpmn")
.deploy();
LOGGER.debug("流程【{}】发布成功,流程ID为:{}", deploymentName, deployment.getId());
}
}
}
/**
* Copyright (c) 2017 Avant-Port All Rights Reserved.
*/
package com.avp.mem.njpb.config.handler;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* Created by Amber Wang on 2017-08-18 下午 06:04.
*/
@Component
public class CustomCreateEventHandler implements TaskListener {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomCreateEventHandler.class);
@Autowired
private IdentityService identityService;
@Autowired
private RuntimeService runtimeService;
@PostConstruct
void init() {
LOGGER.debug("bean customCreateEventHandler is creating...");
}
/**
* 监听每个task的create事件
*
* @param delegateTask
*/
@Override
public void notify(DelegateTask delegateTask) {
String assignEmployee = (String) runtimeService.getVariable(delegateTask.getExecutionId(), "taskAssignEmployee");
String processInstanceId = delegateTask.getProcessInstanceId();
String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
String currentActivityId = delegateTask.getExecution().getCurrentActivityId();
LOGGER.debug("流程id为:{},taskDefinitionKey:{},currentActivityId:{},assignEmployee:{}", processInstanceId, taskDefinitionKey, currentActivityId, assignEmployee);
delegateTask.setAssignee(assignEmployee);
}
}
/**
* Copyright (c) 2017 Avant-Port All Rights Reserved.
*/
package com.avp.mem.njpb.config.handler;
import com.avp.mem.njpb.entity.workorder.ObjWorkOrder;
import com.avp.mem.njpb.repository.workorder.ObjWorkOrderRepository;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* Created by Amber Wang on 2017-08-18 下午 06:04.
*/
@Component
public class CustomTakeEventHandler implements ExecutionListener {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomTakeEventHandler.class);
@Autowired
private IdentityService identityService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private ObjWorkOrderRepository objWorkOrderRepository;
@PostConstruct
void init() {
LOGGER.debug("bean customTakeEventHandler is creating...");
}
@Override
public void notify(DelegateExecution delegateExecution) throws Exception {
String processInstanceId = delegateExecution.getProcessInstanceId();
LOGGER.debug("take事件触发,流程id为:{}", processInstanceId);
ObjWorkOrder objWorkOrder = objWorkOrderRepository.findByProcessInstanceId(processInstanceId);
Integer assignEmployee = objWorkOrder.getAssignEmployee();
LOGGER.debug("工单:{}的调度人为:{}", objWorkOrder.getId(), assignEmployee);
delegateExecution.setVariable("taskAssignEmployee", assignEmployee);
}
}
/**
* Copyright (c) 2017 Avant-Port All Rights Reserved.
*/
package com.avp.mem.njpb.service.activiti;
import com.avp.mem.njpb.entity.stock.ObjStockWorkOrder;
import com.avp.mem.njpb.entity.workorder.ObjWorkOrder;
import com.avp.mem.njpb.util.Validator;
import org.activiti.engine.FormService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 该部分功能点:启动维修工单流程、获取下一节点操作、完成节点任务
*
* Created by Amber Wang on 2017-07-04 下午 03:56.
*/
@Service
@Transactional
public class ActivitiService {
private static Logger LOGGER = LoggerFactory.getLogger(WorkOrderWorkflowService.class);
@Autowired
protected RepositoryService repositoryService;
@Autowired
protected FormService formService;
@Autowired
protected RuntimeService runtimeService;
@Autowired
protected TaskService taskService;
@Autowired
protected IdentityService identityService;
@Value("${business.service.processKey}")
private String repairWoProcessKey;
@Value("${business.service.processKeyOfStock}")
private String stockWoProcessKey;
/**
* 启动维修工单流程
*
* @param entity
*/
public String startRepairWorkflow(ObjWorkOrder entity) {
String businessKey = entity.getId().toString();
ProcessInstance processInstance = null;
String processInstanceId = "";
try {
// 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
identityService.setAuthenticatedUserId(entity.getCreateBy().toString());
Map params = new HashMap<>();
params.put("taskAssignEmployee", entity.getAssignEmployee().toString());
processInstance = runtimeService.startProcessInstanceByKey(repairWoProcessKey, businessKey, params);
processInstanceId = processInstance.getId();
LOGGER.debug("start process of key={}, businessKey={}, processInstanceId={}", entity.getId(), businessKey, processInstanceId);
} finally {
identityService.setAuthenticatedUserId(null);
}
return processInstanceId;
}
/**
* 获取下一节点操作
*
* @param processInstanceId
* @return
* @throws Exception
*/
public List getTaskOperation(String processInstanceId) throws Exception {
List nextOperation = new ArrayList<>();
/*Execution execution = runtimeService.createExecutionQuery().executionId(processInstanceId).singleResult();//执行实例
Object property = PropertyUtils.getProperty(execution, "activityId");
String activityId = "";
if (property != null) {
activityId = property.toString();
}
*/
Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
if (Validator.isNull(task)) {
LOGGER.debug("该流程:{}已经完成", processInstanceId);
return nextOperation;
}
String activityId = task.getTaskDefinitionKey();
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
.singleResult();
ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(processInstance.getProcessDefinitionId());
// ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
// .singleResult();
// ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
// .getDeployedProcessDefinition(processInstance.getProcessDefinitionId());
ActivityImpl activityImpl = processDefinition.findActivity(activityId);
List outTransitions = activityImpl.getOutgoingTransitions();
for (PvmTransition tr : outTransitions) {
String type = (String) tr.getDestination().getProperty("type");
if ("exclusiveGateway".equals(type)) {
//说明是网关
PvmActivity ac = tr.getDestination(); //获取线路的终点节点
System.out.println("下一步任务任务:" + ac.getProperty("name"));
List pvmTransitions = ac.getOutgoingTransitions();
pvmTransitions.forEach(pvmTransition -> {
LOGGER.debug("网关的操作为:{}", pvmTransition.getId());
nextOperation.add(pvmTransition.getId());
});
} else if ("userTask".equals(type) || "endEvent".equals(type)) {
//TODO 判断是task获取当前的flowid
LOGGER.debug("节点类型是userTask或者endEvent,flow ID是:{}", tr.getId());
nextOperation.add(tr.getId());
}
}
return nextOperation;
}
/**
* 完成节点任务
*
* @param taskVariables
* @param processInstanceId
*/
public void completeTask(Map taskVariables, String processInstanceId) {
taskVariables.forEach((k, v) -> System.out.println("task参数----> key : " + k + " value : " + v));
// 设置当前任务信息
Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().orderByTaskCreateTime().desc().singleResult();
LOGGER.debug("task:{},名称为:{}", task.getId(), task.getName());
taskService.complete(task.getId(), taskVariables);
LOGGER.debug("Task:{}完成,参数为:{}", task.getId(), taskVariables.toString());
}
}
/**
* Copyright (c) 2017 Avant-Port All Rights Reserved.
*/
package com.avp.mem.njpb.controller;
import com.avp.mem.njpb.api.rest.ResponseBuilder;
import com.avp.mem.njpb.api.rest.ResponseCode;
import com.avp.mem.njpb.api.rest.RestBody;
import com.avp.mem.njpb.config.ExtensionOperation;
import com.avp.mem.njpb.entity.workorder.ObjWorkOrder;
import com.avp.mem.njpb.service.activiti.ActivitiService;
import com.avp.mem.njpb.util.Validator;
import org.activiti.engine.FormService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.beanutils.PropertyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Amber Wang on 2017-07-07 下午 04:41.
*/
@RestController
public class ActivitiController {
private static final Logger LOGGER = LoggerFactory.getLogger(ActivitiController.class);
@Autowired
protected RepositoryService repositoryService;
@Autowired
protected FormService formService;
@Autowired
protected RuntimeService runtimeService;
@Autowired
protected TaskService taskService;
@Autowired
protected IdentityService identityService;
@Autowired
private ActivitiService activitiService;
/**
* 重新部署流程
*
* @return
*/
@RequestMapping(value = "workflows/redeploy")
public ResponseEntity redeployAll() {
ResponseBuilder build = ResponseBuilder.createBuilder();
try {
String deploymentName = "workorder processes";
Deployment deployment = repositoryService.createDeployment()
.name(deploymentName)
.addClasspathResource("diagrams/workorder/workorder.bpmn")
.deploy();
String deploymentId = deployment.getId();
LOGGER.debug("流程重新部署成功,流程ID:{}", deploymentId);
build.setResponseCode(ResponseCode.UPDATE_SUCCEED, "流程【" + deploymentId + "】重新部署成功");
} catch (Exception e) {
e.printStackTrace();
build.setResponseCode(ResponseCode.BAD_REQUEST, "流程重新部署失败");
}
return build.getResponseEntity();
}
/**
* 重新部署流程
*
* @return
*/
@RequestMapping(value = "stockWorkflows/redeploy")
public ResponseEntity redeployStockAll() {
ResponseBuilder build = ResponseBuilder.createBuilder();
try {
String deploymentNameOfStock = "stockWorkOrder processes";
Deployment deployment = repositoryService.createDeployment()
.name(deploymentNameOfStock)
.addClasspathResource("diagrams/workorder/stockWorkOrder.bpmn")
.deploy();
String deploymentId = deployment.getId();
LOGGER.debug("流程重新部署成功,流程ID:{}", deploymentId);
build.setResponseCode(ResponseCode.UPDATE_SUCCEED, "流程【" + deploymentId + "】重新部署成功");
} catch (Exception e) {
e.printStackTrace();
build.setResponseCode(ResponseCode.BAD_REQUEST, "流程重新部署失败");
}
return build.getResponseEntity();
}
/**
* 查询角色的待办事项--暂不使用
*
* @param role
* @return
*/
@RequestMapping(value = "workflows/getTaskByRole")
public ResponseEntity getTaskByRole(String role) {
ResponseBuilder build = ResponseBuilder.createBuilder();
try {
List tasks = taskService.createTaskQuery().taskCandidateGroup(role).list();
for (Task task : tasks) {
LOGGER.debug("Following task is available for sales group:{},group is :{}", task.getName(), role);
//为工单表中存放的id
String processInstanceId = task.getProcessInstanceId();
LOGGER.debug("工单中的流程id为:{}", processInstanceId);
}
} catch (Exception e) {
e.printStackTrace();
build.setResponseCode(ResponseCode.BAD_REQUEST, "流程重新部署失败");
}
return build.getResponseEntity();
}
//获取当前人的任务
@RequestMapping(value = "/tasks", method = RequestMethod.GET)
public List
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.activiti.org/test">
<process id="process-workorder" name="工单流程" isExecutable="true">
<startEvent id="startevent" name="Start">startEvent>
<userTask id="usertask_report_check" name="报修审核">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}">activiti:taskListener>
extensionElements>
userTask>
<userTask id="usertask_modify_report" name="调整报修内容">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}">activiti:taskListener>
extensionElements>
userTask>
<userTask id="usertask_repair_check" name="维修审核">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}">activiti:taskListener>
extensionElements>
userTask>
<userTask id="usertask_confirm_wo" name="工单确认">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}">activiti:taskListener>
extensionElements>
userTask>
<userTask id="usertask_reAssign" name="工单再次派发" activiti:assignee="${woAssignEmployee}">
userTask>
<userTask id="usertask_repair" name="工单维修">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}">activiti:taskListener>
extensionElements>
userTask>
<userTask id="usertask_sign_in" name="工单签到">
<extensionElements>
<activiti:taskListener event="create"
delegateExpression="${customCreateEventHandler}">activiti:taskListener>
extensionElements>
userTask>
<endEvent id="endevent" name="End">endEvent>
<exclusiveGateway id="exclusivegateway_reportCheck" name="Exclusive Gateway1">exclusiveGateway>
<exclusiveGateway id="exclusivegateway_reReport" name="Parallel Gateway">exclusiveGateway>
<sequenceFlow id="flow_reportWo" name="报修" sourceRef="startevent"
targetRef="usertask_report_check">sequenceFlow>
<sequenceFlow id="flow_report_agree" name="报修审核同意" sourceRef="exclusivegateway_reportCheck"
targetRef="usertask_confirm_wo">
<conditionExpression xsi:type="tFormalExpression">conditionExpression>
sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask_report_check"
targetRef="exclusivegateway_reportCheck">sequenceFlow>
<sequenceFlow id="flow_report_reject" name="报修审核不同意" sourceRef="exclusivegateway_reportCheck"
targetRef="usertask_modify_report">
<conditionExpression xsi:type="tFormalExpression">
conditionExpression>
sequenceFlow>
<sequenceFlow id="flow_endReport" name="结束报修流程" sourceRef="exclusivegateway_reReport" targetRef="endevent">
<conditionExpression xsi:type="tFormalExpression">conditionExpression>
sequenceFlow>
<sequenceFlow id="flow6" sourceRef="usertask_modify_report"
targetRef="exclusivegateway_reReport">sequenceFlow>
<sequenceFlow id="flow_reReport" name="重新报修" sourceRef="exclusivegateway_reReport"
targetRef="usertask_report_check">
<conditionExpression xsi:type="tFormalExpression">conditionExpression>
sequenceFlow>
<sequenceFlow id="flow_reAssign" name="再次派发" sourceRef="usertask_reAssign"
targetRef="usertask_confirm_wo">sequenceFlow>
<sequenceFlow id="flow_repair_check" name="工单完成" sourceRef="usertask_repair_check" targetRef="endevent">sequenceFlow>
<sequenceFlow id="flow_repair_complete" name="维修完成或遗留" sourceRef="usertask_repair"
targetRef="usertask_repair_check">sequenceFlow>
<sequenceFlow id="flow_confirm_wo" name="工单确认" sourceRef="usertask_confirm_wo"
targetRef="usertask_sign_in">sequenceFlow>
<sequenceFlow id="flow_sign_in" name="签到" sourceRef="usertask_sign_in"
targetRef="usertask_repair">sequenceFlow>
<boundaryEvent id="boundarytimer2" name="Timer" attachedToRef="usertask_confirm_wo" cancelActivity="true">
<timerEventDefinition>
<timeDuration>${responseTimeOut_time}timeDuration>
timerEventDefinition>
boundaryEvent>
<sequenceFlow id="flow_response_timeout" name="响应超时" sourceRef="boundarytimer2" targetRef="usertask_reAssign">
sequenceFlow>
process>
<bpmndi:BPMNDiagram id="BPMNDiagram_process-workorder">
<bpmndi:BPMNPlane bpmnElement="process-workorder" id="BPMNPlane_process-workorder">
<bpmndi:BPMNShape bpmnElement="startevent" id="BPMNShape_startevent">
<omgdc:Bounds height="35.0" width="35.0" x="1.0" y="120.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_report_check" id="BPMNShape_usertask_report_check">
<omgdc:Bounds height="60.0" width="100.0" x="113.0" y="108.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_modify_report" id="BPMNShape_usertask_modify_report">
<omgdc:Bounds height="60.0" width="100.0" x="357.0" y="335.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_repair_check" id="BPMNShape_usertask_repair_check">
<omgdc:Bounds height="60.0" width="100.0" x="1050.0" y="478.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_confirm_wo" id="BPMNShape_usertask_confirm_wo">
<omgdc:Bounds height="60.0" width="100.0" x="640.0" y="106.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="boundarytimer2" id="BPMNShape_boundarytimer2">
<omgdc:Bounds height="30.0" width="30.0" x="712.0" y="132.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_reAssign" id="BPMNShape_usertask_reAssign">
<omgdc:Bounds height="60.0" width="100.0" x="677.0" y="310.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_repair" id="BPMNShape_usertask_repair">
<omgdc:Bounds height="60.0" width="100.0" x="1090.0" y="255.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask_sign_in" id="BPMNShape_usertask_sign_in">
<omgdc:Bounds height="60.0" width="100.0" x="1240.0" y="108.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent" id="BPMNShape_endevent">
<omgdc:Bounds height="35.0" width="35.0" x="649.0" y="490.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway_reportCheck" id="BPMNShape_exclusivegateway_reportCheck">
<omgdc:Bounds height="40.0" width="40.0" x="392.0" y="115.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway_reReport" id="BPMNShape_exclusivegateway_reReport">
<omgdc:Bounds height="40.0" width="40.0" x="142.0" y="487.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow_reportWo" id="BPMNEdge_flow_reportWo">
<omgdi:waypoint x="36.0" y="137.0">omgdi:waypoint>
<omgdi:waypoint x="113.0" y="138.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="24.0" x="59.0" y="115.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_report_agree" id="BPMNEdge_flow_report_agree">
<omgdi:waypoint x="432.0" y="135.0">omgdi:waypoint>
<omgdi:waypoint x="640.0" y="136.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="72.0" x="488.0" y="115.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="213.0" y="138.0">omgdi:waypoint>
<omgdi:waypoint x="392.0" y="135.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_report_reject" id="BPMNEdge_flow_report_reject">
<omgdi:waypoint x="412.0" y="155.0">omgdi:waypoint>
<omgdi:waypoint x="407.0" y="335.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="84.0" x="363.0" y="241.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_endReport" id="BPMNEdge_flow_endReport">
<omgdi:waypoint x="182.0" y="507.0">omgdi:waypoint>
<omgdi:waypoint x="649.0" y="507.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="72.0" x="357.0" y="491.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="407.0" y="395.0">omgdi:waypoint>
<omgdi:waypoint x="162.0" y="487.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_reReport" id="BPMNEdge_flow_reReport">
<omgdi:waypoint x="162.0" y="487.0">omgdi:waypoint>
<omgdi:waypoint x="163.0" y="168.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="110.0" y="395.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_reAssign" id="BPMNEdge_flow_reAssign">
<omgdi:waypoint x="677.0" y="340.0">omgdi:waypoint>
<omgdi:waypoint x="605.0" y="344.0">omgdi:waypoint>
<omgdi:waypoint x="690.0" y="166.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="588.0" y="273.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_repair_check" id="BPMNEdge_flow_repair_check">
<omgdi:waypoint x="1050.0" y="508.0">omgdi:waypoint>
<omgdi:waypoint x="684.0" y="507.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_repair_complete" id="BPMNEdge_flow_repair_complete">
<omgdi:waypoint x="1140.0" y="315.0">omgdi:waypoint>
<omgdi:waypoint x="1100.0" y="478.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="84.0" x="1116.0" y="395.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_confirm_wo" id="BPMNEdge_flow_confirm_wo">
<omgdi:waypoint x="740.0" y="136.0">omgdi:waypoint>
<omgdi:waypoint x="1240.0" y="138.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="950.0" y="115.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_sign_in" id="BPMNEdge_flow_sign_in">
<omgdi:waypoint x="1290.0" y="168.0">omgdi:waypoint>
<omgdi:waypoint x="1140.0" y="255.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="24.0" x="1241.0" y="202.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow_response_timeout" id="BPMNEdge_flow_response_timeout">
<omgdi:waypoint x="727.0" y="162.0">omgdi:waypoint>
<omgdi:waypoint x="820.0" y="344.0">omgdi:waypoint>
<omgdi:waypoint x="777.0" y="340.0">omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="752.0" y="255.0">omgdc:Bounds>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
bpmndi:BPMNPlane>
bpmndi:BPMNDiagram>
definitions>
<dependency>
<groupId>org.activitigroupId>
<artifactId>spring-boot-starter-basicartifactId>
<version>5.17.0version>
dependency>