public Object execute(CommandContext commandContext) {
    if (processInstanceId == null) {
      throw new ActivitiException("processInstanceId is null");
    }
    // Check if process instance is still running
    HistoricProcessInstance instance =
        commandContext
            .getHistoricProcessInstanceManager()
            .findHistoricProcessInstance(processInstanceId);

    if (instance == null) {
      throw new ActivitiException(
          "No historic process instance found with id: " + processInstanceId);
    }
    if (instance.getEndTime() == null) {
      throw new ActivitiException(
          "Process instance is still running, cannot delete historic process instance: "
              + processInstanceId);
    }

    commandContext
        .getHistoricProcessInstanceManager()
        .deleteHistoricProcessInstanceById(processInstanceId);

    return null;
  }
Exemple #2
0
 /**
  * 获取流程详细及工作流参数
  *
  * @param id
  */
 @SuppressWarnings("unchecked")
 public Leave get(String id) {
   Leave leave = leaveDao.get(id);
   Map<String, Object> variables = null;
   HistoricProcessInstance historicProcessInstance =
       historyService
           .createHistoricProcessInstanceQuery()
           .processInstanceId(leave.getProcessInstanceId())
           .singleResult();
   if (historicProcessInstance != null) {
     variables =
         Collections3.extractToMap(
             historyService
                 .createHistoricVariableInstanceQuery()
                 .processInstanceId(historicProcessInstance.getId())
                 .list(),
             "variableName",
             "value");
   } else {
     variables =
         runtimeService.getVariables(
             runtimeService
                 .createProcessInstanceQuery()
                 .processInstanceId(leave.getProcessInstanceId())
                 .active()
                 .singleResult()
                 .getId());
   }
   leave.setVariables(variables);
   return leave;
 }
 /**
  * 根据流程实例ID查询流程定义对象{@link ProcessDefinition}
  *
  * @param processInstanceId 流程实例ID
  * @return 流程定义对象{@link ProcessDefinition}
  */
 public ProcessDefinition findProcessDefinitionByPid(String processInstanceId) {
   HistoricProcessInstance historicProcessInstance =
       historyService
           .createHistoricProcessInstanceQuery()
           .processInstanceId(processInstanceId)
           .singleResult();
   String processDefinitionId = historicProcessInstance.getProcessDefinitionId();
   ProcessDefinition processDefinition = findProcessDefinition(processDefinitionId);
   return processDefinition;
 }
  protected ProcessInstanceItem createItem(HistoricProcessInstance processInstance) {
    ProcessInstanceItem item = new ProcessInstanceItem();
    item.addItemProperty("id", new ObjectProperty<String>(processInstance.getId(), String.class));

    ProcessDefinition processDefinition =
        getProcessDefinition(processInstance.getProcessDefinitionId());

    String itemName =
        getProcessDisplayName(processDefinition) + " (" + processInstance.getId() + ")";
    item.addItemProperty("name", new ObjectProperty<String>(itemName, String.class));
    return item;
  }
  public void drawHistoryFlow(BufferedImage image, String processInstanceId) {
    HistoricProcessInstance historicProcessInstance =
        Context.getCommandContext()
            .getHistoricProcessInstanceEntityManager()
            .findHistoricProcessInstance(processInstanceId);
    String processDefinitionId = historicProcessInstance.getProcessDefinitionId();
    Graph graph = new ActivitiHistoryGraphBuilder(processInstanceId).build();

    for (Edge edge : graph.getEdges()) {
      drawSequenceFlow(image, processDefinitionId, edge.getName());
    }
  }
Exemple #6
0
  @SuppressWarnings("serial")
  /**
   * Creates a popup that allows to see the process history and the final report of
   * historicProcessInstance
   *
   * @param historicProcessInstance = historicProcessInstance to be seen
   * @return the popup of historicProcessInstance
   */
  private PopupView createHistoricProcessInstancePopup(
      final HistoricProcessInstance historicProcessInstance) {
    final VerticalLayout layout = new VerticalLayout();
    final PopupView popup = new PopupView(historicProcessInstance.getId(), layout);

    layout.setSizeUndefined();
    layout.setMargin(true);
    layout.setSpacing(true);
    Label header =
        new Label(
            String.format(
                "What would you like to do with process: <b>%s</b>?",
                historicProcessInstance.getId()));
    header.setContentMode(Label.CONTENT_XHTML);
    layout.addComponent(header);

    Button porcessHistory = new Button("See process history");
    porcessHistory.addStyleName(Reindeer.BUTTON_SMALL);
    porcessHistory.addListener(
        new Button.ClickListener() {

          @Override
          public void buttonClick(ClickEvent event) {
            getPresenter().setHistBrowser(historicProcessInstance);
            popup.setPopupVisible(false);
          }
        });
    layout.addComponent(porcessHistory);

    Button finalReport = new Button("see final report");
    finalReport.addStyleName(Reindeer.BUTTON_SMALL);
    finalReport.addListener(
        new Button.ClickListener() {

          @Override
          public void buttonClick(ClickEvent event) {
            getPresenter().setReportBrowser(historicProcessInstance);
            popup.setPopupVisible(false);
          }
        });
    layout.addComponent(finalReport);

    return popup;
  }
  /**
   * Process variation over time i.e. tasks started and completed over the months
   *
   * @return array with the no. of processes started and completed over the months
   */
  @GET
  @Path("/processVariation/")
  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  public ResponseHolder processVariationOverTime() {
    ResponseHolder response = new ResponseHolder();
    List list = new ArrayList();
    String[] MONTHS = {
      "Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"
    };
    SimpleDateFormat ft = new SimpleDateFormat("M");
    InstanceStatPerMonth[] processStatPerMonths = new InstanceStatPerMonth[12];
    for (int i = 0; i < processStatPerMonths.length; i++) {
      processStatPerMonths[i] = new InstanceStatPerMonth();
      processStatPerMonths[i].setMonth(MONTHS[i]);
      processStatPerMonths[i].setCompletedInstances(0);
      processStatPerMonths[i].setStartedInstances(0);
    }

    // Get completed process instances
    List<HistoricProcessInstance> completedProcesses =
        BPMNOSGIService.getHistoryService()
            .createHistoricProcessInstanceQuery()
            .processInstanceTenantId(str)
            .finished()
            .list();
    for (HistoricProcessInstance instance : completedProcesses) {
      int startTime = Integer.parseInt(ft.format(instance.getStartTime()));
      int endTime = Integer.parseInt(ft.format(instance.getEndTime()));
      processStatPerMonths[startTime - 1].setStartedInstances(
          processStatPerMonths[startTime - 1].getStartedInstances() + 1);
      processStatPerMonths[endTime - 1].setCompletedInstances(
          processStatPerMonths[endTime - 1].getCompletedInstances() + 1);
    }
    // Get active process instances
    List<HistoricProcessInstance> activeProcesses =
        BPMNOSGIService.getHistoryService()
            .createHistoricProcessInstanceQuery()
            .processInstanceTenantId(str)
            .unfinished()
            .list();
    for (HistoricProcessInstance instance : activeProcesses) {
      int startTime = Integer.parseInt(ft.format(instance.getStartTime()));
      processStatPerMonths[startTime - 1].setStartedInstances(
          processStatPerMonths[startTime - 1].getStartedInstances() + 1);
    }

    for (int i = 0; i < processStatPerMonths.length; i++) {
      list.add(processStatPerMonths[i]);
    }
    response.setData(list);
    return response;
  }
  protected void addHeader() {
    GridLayout header = new GridLayout(3, 2);
    header.setWidth(100, UNITS_PERCENTAGE);
    header.addStyleName(ExplorerLayout.STYLE_TITLE_BLOCK);
    header.setSpacing(true);
    header.setMargin(false, false, true, false);

    // Add image
    Embedded image = new Embedded(null, Images.PROCESS_50);
    header.addComponent(image, 0, 0, 0, 1);

    // Add task name
    Label nameLabel = new Label(getProcessDisplayName(processDefinition, processInstance));
    nameLabel.addStyleName(Reindeer.LABEL_H2);
    header.addComponent(nameLabel, 1, 0, 2, 0);

    // Add start time
    PrettyTimeLabel startTimeLabel =
        new PrettyTimeLabel(
            i18nManager.getMessage(Messages.PROCESS_START_TIME),
            historicProcessInstance.getStartTime(),
            null,
            true);
    startTimeLabel.addStyleName(ExplorerLayout.STYLE_PROCESS_HEADER_START_TIME);
    header.addComponent(startTimeLabel, 1, 1);

    header.setColumnExpandRatio(1, 1.0f);
    header.setColumnExpandRatio(2, 1.0f);

    panelLayout.addComponent(header);
  }
Exemple #9
0
  public Page<Leave> find(Page<Leave> page, Leave leave) {

    leave.getSqlMap().put("dsf", dataScopeFilter(leave.getCurrentUser(), "o", "u"));

    leave.setPage(page);
    page.setList(leaveDao.findList(leave));

    for (Leave item : page.getList()) {
      String processInstanceId = item.getProcessInstanceId();
      Task task =
          taskService
              .createTaskQuery()
              .processInstanceId(processInstanceId)
              .active()
              .singleResult();
      item.setTask(task);
      HistoricProcessInstance historicProcessInstance =
          historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceId(processInstanceId)
              .singleResult();
      if (historicProcessInstance != null) {
        item.setHistoricProcessInstance(historicProcessInstance);
        item.setProcessDefinition(
            repositoryService
                .createProcessDefinitionQuery()
                .processDefinitionId(historicProcessInstance.getProcessDefinitionId())
                .singleResult());
      } else {
        ProcessInstance processInstance =
            runtimeService
                .createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .active()
                .singleResult();
        if (processInstance != null) {
          item.setProcessInstance(processInstance);
          item.setProcessDefinition(
              repositoryService
                  .createProcessDefinitionQuery()
                  .processDefinitionId(processInstance.getProcessDefinitionId())
                  .singleResult());
        }
      }
    }
    return page;
  }
  /**
   * Get the average time duration of completed processes
   *
   * @return list with the completed processes and the average time duration taken for each process
   */
  @GET
  @Path("/avgDurationToCompleteProcess/")
  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  public ResponseHolder getAvgTimeDurationForCompletedProcesses() {
    List<ProcessDefinition> deployements =
        BPMNOSGIService.getRepositoryService()
            .createProcessDefinitionQuery()
            .processDefinitionTenantId(str)
            .list();

    ResponseHolder response = new ResponseHolder();
    List list = new ArrayList<>();

    for (ProcessDefinition instance : deployements) {
      CompletedProcesses bpmnProcessInstance = new CompletedProcesses();
      bpmnProcessInstance.setProcessDefinitionId(instance.getId());

      double totalTime = 0;
      double averageTime = 0;
      String processDefinitionID = instance.getId();

      HistoricProcessInstanceQuery historicProcessInstanceQuery =
          BPMNOSGIService.getHistoryService()
              .createHistoricProcessInstanceQuery()
              .processInstanceTenantId(str)
              .processDefinitionId(processDefinitionID)
              .finished();

      long noOfHistoricInstances = historicProcessInstanceQuery.count();

      if (noOfHistoricInstances == 0) {
      } else {
        List<HistoricProcessInstance> instanceList = historicProcessInstanceQuery.list();

        for (HistoricProcessInstance completedProcess : instanceList) {
          double timeDurationOfTask = completedProcess.getDurationInMillis();
          double timeInMins = timeDurationOfTask / (1000 * 60);
          totalTime += timeInMins;
        }
        averageTime = totalTime / noOfHistoricInstances;
        bpmnProcessInstance.setAverageTimeForCompletion(averageTime);
        list.add(bpmnProcessInstance);
      }
    }
    response.setData(list);
    return response;
  }
  @SuppressWarnings("unchecked")
  public void deleteHistoricProcessInstanceById(String historicProcessInstanceId) {
    if (getHistoryManager().isHistoryEnabled()) {
      CommandContext commandContext = Context.getCommandContext();
      HistoricProcessInstanceEntity historicProcessInstance =
          findHistoricProcessInstance(historicProcessInstanceId);

      commandContext
          .getHistoricDetailEntityManager()
          .deleteHistoricDetailsByProcessInstanceId(historicProcessInstanceId);

      commandContext
          .getHistoricVariableInstanceEntityManager()
          .deleteHistoricVariableInstanceByProcessInstanceId(historicProcessInstanceId);

      commandContext
          .getHistoricActivityInstanceEntityManager()
          .deleteHistoricActivityInstancesByProcessInstanceId(historicProcessInstanceId);

      commandContext
          .getHistoricTaskInstanceEntityManager()
          .deleteHistoricTaskInstancesByProcessInstanceId(historicProcessInstanceId);

      commandContext
          .getHistoricIdentityLinkEntityManager()
          .deleteHistoricIdentityLinksByProcInstance(historicProcessInstanceId);

      commandContext
          .getCommentEntityManager()
          .deleteCommentsByProcessInstanceId(historicProcessInstanceId);

      getDbSqlSession().delete(historicProcessInstance);

      // Also delete any sub-processes that may be active (ACT-821)
      HistoricProcessInstanceQueryImpl subProcessesQueryImpl =
          new HistoricProcessInstanceQueryImpl();
      subProcessesQueryImpl.superProcessInstanceId(historicProcessInstanceId);

      List<HistoricProcessInstance> selectList =
          getDbSqlSession()
              .selectList("selectHistoricProcessInstancesByQueryCriteria", subProcessesQueryImpl);
      for (HistoricProcessInstance child : selectList) {
        deleteHistoricProcessInstanceById(child.getId());
      }
    }
  }
Exemple #12
0
  public HumanTaskDTO createHumanTask(
      DelegateTask delegateTask, HistoricTaskInstanceEntity historicTaskInstanceEntity)
      throws Exception {
    HumanTaskConnector humanTaskConnector =
        ApplicationContextHelper.getBean(HumanTaskConnector.class);
    HumanTaskDTO humanTaskDto = new HumanTaskBuilder().setDelegateTask(delegateTask).build();

    if ("发起流程".equals(historicTaskInstanceEntity.getDeleteReason())) {
      humanTaskDto.setCatalog(HumanTaskConstants.CATALOG_START);
    }

    HistoricProcessInstance historicProcessInstance =
        Context.getCommandContext()
            .getHistoricProcessInstanceEntityManager()
            .findHistoricProcessInstance(delegateTask.getProcessInstanceId());
    humanTaskDto.setProcessStarter(historicProcessInstance.getStartUserId());
    humanTaskDto = humanTaskConnector.saveHumanTask(humanTaskDto);

    return humanTaskDto;
  }
  @Deployment
  public void testDeeplyNestedErrorThrownOnlyAutomaticSteps() {
    // input == 1 -> error2 is thrown -> caught on subprocess2 -> end event in subprocess -> proc
    // inst end 1
    String procId =
        runtimeService
            .startProcessInstanceByKey(
                "deeplyNestedErrorThrown", CollectionUtil.singletonMap("input", 1))
            .getId();
    assertProcessEnded(procId);

    HistoricProcessInstance hip;
    if (processEngineConfiguration.getHistoryLevel().isAtLeast(HistoryLevel.ACTIVITY)) {
      hip =
          historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceId(procId)
              .singleResult();
      assertEquals("processEnd1", hip.getEndActivityId());
    }
    // input == 2 -> error2 is thrown -> caught on subprocess1 -> proc inst end 2
    procId =
        runtimeService
            .startProcessInstanceByKey(
                "deeplyNestedErrorThrown", CollectionUtil.singletonMap("input", 1))
            .getId();
    assertProcessEnded(procId);

    if (processEngineConfiguration.getHistoryLevel().isAtLeast(HistoryLevel.ACTIVITY)) {
      hip =
          historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceId(procId)
              .singleResult();
      assertEquals("processEnd1", hip.getEndActivityId());
    }
  }
 @Test
 @Deployment(resources = {"chapter4/bookorder.bpmn20.xml"})
 public void queryHistoricInstances() {
   String processInstanceID = startAndComplete();
   HistoryService historyService = activitiRule.getHistoryService();
   HistoricProcessInstance historicProcessInstance =
       historyService
           .createHistoricProcessInstanceQuery()
           .processInstanceId(processInstanceID)
           .singleResult();
   assertNotNull(historicProcessInstance);
   assertEquals(processInstanceID, historicProcessInstance.getId());
   System.out.println(
       "history process with definition id "
           + historicProcessInstance.getProcessDefinitionId()
           + ", started at "
           + historicProcessInstance.getStartTime()
           + ", ended at "
           + historicProcessInstance.getEndTime()
           + ", duration was "
           + historicProcessInstance.getDurationInMillis());
 }
  /**
   * @Title: myWorkTaskData @Description: TODO
   *
   * @param request
   * @param response
   * @param dataGrid void
   * @throws
   * @exception
   * @author fly
   * @date 2015年6月23日 上午10:20:42
   */
  @RequestMapping(params = "myWorkTaskData")
  public void myWorkTaskData(
      HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid) {

    String userId = ResourceUtil.getSessionUserName().getId();
    // involvedUser 当前用户相关的
    HistoricProcessInstanceQuery query =
        historyService.createHistoricProcessInstanceQuery().involvedUser(userId);

    List<HistoricProcessInstance> historicTasks =
        query
            .orderByProcessInstanceStartTime()
            .desc()
            .listPage(dataGrid.getStart(), dataGrid.getEnd());
    long total = query.count();
    System.out.println(dataGrid.getStart() + " end: " + dataGrid.getEnd());
    StringBuffer rows = new StringBuffer();
    for (HistoricProcessInstance t : historicTasks) {
      ProcessDefinition processDefinition =
          repositoryService.getProcessDefinition(t.getProcessDefinitionId());

      rows.append(
          "{'id':'"
              + t.getId()
              + "','key':'"
              + processDefinition.getName()
              + "-"
              + DateUtils.date_sdf.format(t.getStartTime())
              + "','taskId':'"
              + t.getId()
              + "'");
      // 流程详细查看
      WorkFlowSetEntity workFlowSet =
          systemService.findUniqueByProperty(
              WorkFlowSetEntity.class, "deploymentId", processDefinition.getDeploymentId());
      if (workFlowSet != null) {
        rows.append(",'action':'" + workFlowSet.getDetailUrl() + "'");
      }
      // 流程用户处理
      if (t.getStartUserId() != null) {
        TSUser user = systemService.get(TSUser.class, t.getStartUserId());
        rows.append(",'username':'******'");
      }

      // 流程开始结束时间处理
      if (t.getStartTime() == null) {
        rows.append(",'beginDate':'无'");
      } else {
        rows.append(",'beginDate':'" + DateUtils.datetimeFormat.format(t.getStartTime()) + "'");
      }
      if (t.getEndTime() == null) {
        rows.append(",'endDate':'无','stateType':'办理中'");

      } else {
        rows.append(
            ",'endDate':'"
                + DateUtils.datetimeFormat.format(t.getEndTime())
                + "','stateType':'已完成'");
      }
      rows.append("},");
    }
    String rowStr = StringUtils.substringBeforeLast(rows.toString(), ",");

    JSONObject jObject = JSONObject.fromObject("{'total':" + total + ",'rows':[" + rowStr + "]}");
    responseDatagrid(response, jObject);
  }
  @Deployment(
      resources = {
        "org/rill/bpm/api/pg-support_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-managerAudit_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-orderValidityAudit_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-resetOrderReceiptType_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-addmoney_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-contractQualification_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-gift_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-openaccount_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-orderPrint_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-promotionsExpires-contract_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-receiptFounds_v2.bpmn20.xml",
        "org/rill/bpm/api/Pg-support-managerAudit_agt_v2.bpmn20.xml"
      })
  @Test
  public void testPgSupportV2() {

    // Add by MENGRAN at 2012-05-25
    // System.setProperty("activiti.blindRetrieveTimeout", "60");
    Number number = new Constants(ScaleoutHelper.class).asNumber("BLIND_RETRIEVE_TIMEOUT");
    Assert.assertEquals(30L, number.longValue());

    String processDefinitionKey = "Pg-support_v2";
    Integer orderId = new Random().nextInt();
    String processStarter = "Rill Meng";

    DummyOrderAudit orderAudit = new DummyOrderAudit();
    orderAudit.setAuditAction(DummyOrderAudit.AGREE);

    logger.info(
        "Start process by key " + processDefinitionKey + "], and business key[" + orderId + "]");

    // -------------------------------- start Pg-support_v2
    // Start process by KEY
    Map<String, Object> startProcessParams = new HashMap<String, Object>();
    startProcessParams.put("biz_mode", "0");
    List<String> taskList =
        workflowAccessor.createProcessInstance(
            processDefinitionKey, processStarter, orderId.toString(), startProcessParams);
    Assert.assertEquals(2, taskList.size());

    // Check process starter info at 2012-02-07
    String processInstanceId =
        workflowAccessor.getEngineProcessInstanceIdByBOId(orderId.toString(), null);
    for (int i = 0; i < 2; i++) {
      processInstanceId =
          workflowAccessor.getEngineProcessInstanceIdByBOId(orderId.toString(), null);
    }
    ActivitiAccessor activitiAccessor =
        ActivitiAccessor.retrieveActivitiAccessorImpl(workflowAccessor, ActivitiAccessor.class);
    HistoricProcessInstance hisPi =
        activitiAccessor
            .getHistoryService()
            .createHistoricProcessInstanceQuery()
            .processInstanceId(processInstanceId)
            .singleResult();
    Assert.assertEquals(processStarter, hisPi.getStartUserId());
    Assert.assertEquals(null, Authentication.getAuthenticatedUserId());
    User persistentUser =
        activitiAccessor
            .getIdentityService()
            .createUserQuery()
            .userId(processStarter)
            .singleResult();
    Assert.assertEquals(processStarter, persistentUser.getId());

    // Test obtain extend attributes logic
    String manageraudit = null;
    String resetOrderReceiptTypeTaskId = null;
    for (String taskId : taskList) {
      HashMap<String, String> extendAttributes =
          workflowAccessor.getTaskInstanceInformations(taskId);
      Assert.assertNotNull(extendAttributes);
      Assert.assertNotNull(extendAttributes.get(WorkflowTemplate.TASK_ROLE_TAG));
      if (!extendAttributes.get(WorkflowTemplate.TASK_ROLE_TAG).equals("ht_support_khfz_staff")) {
        // manageraudit
        manageraudit = taskId;
        Assert.assertEquals(
            "manageraudit/frontManagerAuditInit.action",
            extendAttributes.get(WorkflowTemplate.TASK_FORM_KEY));
        Assert.assertEquals("status=2", extendAttributes.get("init_status"));
        Assert.assertEquals("12", extendAttributes.get("event"));
        Assert.assertEquals(
            "ht_support_khfzb_manager", extendAttributes.get(WorkflowTemplate.TASK_ROLE_TAG));
        Assert.assertEquals("manageraudit", extendAttributes.get(WorkflowTemplate.TASK_DEFINE_ID));
      } else {
        resetOrderReceiptTypeTaskId = taskId;
      }
    }

    // Complete manageraudit
    Map<String, Object> managerauditWorkflowParams = new HashMap<String, Object>();
    managerauditWorkflowParams.put("need_highlevel_audit", "true");
    managerauditWorkflowParams.put("orderAudit", orderAudit);
    List<String> managerauditResult =
        workflowAccessor.completeTaskInstance(
            manageraudit, "manageraudit", managerauditWorkflowParams);
    Assert.assertEquals(1, managerauditResult.size());
    String seniormanageraudit = managerauditResult.get(0);

    // Complete seniormanageraudit and use exists
    // variables[need_highlevel_audit]
    List<String> seniormanagerauditResult =
        workflowAccessor.completeTaskInstance(seniormanageraudit, "seniormanageraudit", null);
    Assert.assertEquals(1, seniormanagerauditResult.size());
    String directoraudit = seniormanagerauditResult.get(0);

    // Complete directoraudit and change exists
    // variables[need_highlevel_audit] values
    Map<String, Object> directorauditWorkflowParams = new HashMap<String, Object>();
    directorauditWorkflowParams.put("need_highlevel_audit", "false");
    // Set to reject
    orderAudit.setAuditAction(DummyOrderAudit.REJECT);
    directorauditWorkflowParams.put("orderAudit", orderAudit);
    List<String> directorauditResult =
        workflowAccessor.completeTaskInstance(
            directoraudit, "directoraudit", directorauditWorkflowParams);
    Assert.assertEquals(1, directorauditResult.size());
    HashMap<String, String> modorderExtendAttributes =
        workflowAccessor.getTaskInstanceInformations(directorauditResult.get(0));
    Assert.assertEquals("modorder", modorderExtendAttributes.get(WorkflowTemplate.TASK_DEFINE_ID));
    String modorder = directorauditResult.get(0);

    // -------------------------------- re-enter Pg-support-managerAudit_v2
    // Complete modorder
    Map<String, Object> modorderResultWorkflowParams = new HashMap<String, Object>();
    orderAudit.setAuditAction(DummyOrderAudit.AGREE);
    modorderResultWorkflowParams.put("orderAudit", orderAudit);
    List<String> modorderResult =
        workflowAccessor.completeTaskInstance(modorder, "modorder", modorderResultWorkflowParams);
    Assert.assertEquals(1, modorderResult.size());
    HashMap<String, String> managerauditExtendAttributes =
        workflowAccessor.getTaskInstanceInformations(modorderResult.get(0));
    Assert.assertEquals(
        "manageraudit", managerauditExtendAttributes.get(WorkflowTemplate.TASK_DEFINE_ID));
    String manageraudit2 = modorderResult.get(0);

    // Complete manageraudit2
    Map<String, Object> manageraudit2flowParams = new HashMap<String, Object>();
    manageraudit2flowParams.put("need_highlevel_audit", "false");
    orderAudit.setAuditAction(DummyOrderAudit.AGREE);
    manageraudit2flowParams.put("orderAudit", orderAudit);
    List<String> manageraudit2Result =
        workflowAccessor.completeTaskInstance(
            manageraudit2, "manageraudit2", manageraudit2flowParams);
    Assert.assertEquals(1, manageraudit2Result.size());
    HashMap<String, String> preauditExtendAttributes =
        workflowAccessor.getTaskInstanceInformations(manageraudit2Result.get(0));
    Assert.assertEquals("preaudit", preauditExtendAttributes.get(WorkflowTemplate.TASK_DEFINE_ID));
    String preaudit = manageraudit2Result.get(0);

    // Complete preaudit
    List<String> preauditResult = workflowAccessor.completeTaskInstance(preaudit, "preaudit", null);
    Assert.assertEquals(1, preauditResult.size());
    HashMap<String, String> sendcontractExtendAttributes =
        workflowAccessor.getTaskInstanceInformations(preauditResult.get(0));
    Assert.assertEquals(
        "sendcontract", sendcontractExtendAttributes.get(WorkflowTemplate.TASK_DEFINE_ID));
    String sendcontract = preauditResult.get(0);

    // Complete sendcontract
    Map<String, Object> sendcontractflowParams = new HashMap<String, Object>();
    DummyOrder order = new DummyOrder();
    order.setIsNeedGift(DummyOrder.XIAN_TI);
    DummyReceiptInfo receiptInfo = new DummyReceiptInfo();
    receiptInfo.setReceiptType(DummyReceiptInfo.PRE_INVOICE);
    orderAudit.setAuditAction(DummyOrderAudit.AGREE);
    sendcontractflowParams.put("orderAudit", orderAudit);
    sendcontractflowParams.put("order", order);
    sendcontractflowParams.put("receiptInfo", receiptInfo);

    List<String> sendcontractResult =
        workflowAccessor.completeTaskInstance(sendcontract, "sendcontract", sendcontractflowParams);
    // contract finance gift
    Assert.assertEquals(3, sendcontractResult.size());
    String writereceipt = null;
    String auditSendGift = null;
    for (String taskId : sendcontractResult) {
      HashMap<String, String> extendAttributes =
          workflowAccessor.getTaskInstanceInformations(taskId);
      if ("writereceipt"
          .equals(extendAttributes.get(WorkflowOperations.TaskInformations.TASK_TAG.name()))) {
        writereceipt = taskId;
      }
      if ("auditAndSendGift"
          .equals(extendAttributes.get(WorkflowOperations.TaskInformations.TASK_TAG.name()))) {
        auditSendGift = taskId;
      }
    }
    // Fix audit gift Lock timeout
    Map<String, Object> auditGiftSendParams = new HashMap<String, Object>();
    orderAudit.setAuditAction(DummyOrderAudit.AGREE);
    auditGiftSendParams.put("orderAudit", orderAudit);
    List<String> auditGiftSend =
        workflowAccessor.completeTaskInstance(auditSendGift, "RillMeng", auditGiftSendParams);
    Assert.assertEquals(0, auditGiftSend.size());

    processInstanceId = workflowAccessor.getEngineProcessInstanceIdByBOId(orderId.toString(), null);
    Assert.assertNotNull("Root process instance isn't running?", processInstanceId);
    logger.info("process instance[" + processInstanceId + "] is running.");

    // -------------------------------- Pg-support-resetOrderReceiptType_v2
    List<String> auditResetOrderReceiptType =
        workflowAccessor.completeTaskInstance(resetOrderReceiptTypeTaskId, "RillMeng", null);
    Map<String, Object> auditResetOrderReceiptTypeMap = new HashMap<String, Object>();
    orderAudit.setAuditAction(DummyOrderAudit.AGREE);
    auditResetOrderReceiptTypeMap.put("orderAudit", orderAudit);
    auditResetOrderReceiptTypeMap.put("need_highlevel_audit", "false");
    auditResetOrderReceiptType =
        workflowAccessor.completeTaskInstance(
            auditResetOrderReceiptType.get(0), "RillMeng", auditResetOrderReceiptTypeMap);
    Assert.assertEquals(0, auditResetOrderReceiptType.size());

    Map<String, Object> goBackMap = new HashMap<String, Object>();
    goBackMap.put("__go_back", "true");
    receiptInfo.setReceiptType(DummyReceiptInfo.POST_INVOICE);
    goBackMap.put("receiptInfo", receiptInfo);
    List<String> afterGoBack =
        workflowAccessor.completeTaskInstance(
            writereceipt, "auditResetOrderReceiptType", goBackMap);
    HashMap<String, String> extendAttributes =
        workflowAccessor.getTaskInstanceInformations(afterGoBack.get(0));
    Assert.assertEquals(
        "completefinanceinfo",
        extendAttributes.get(WorkflowOperations.TaskInformations.TASK_TAG.name()));
    Assert.assertEquals(1, afterGoBack.size());
    // Complete finance info
    goBackMap = new HashMap<String, Object>();
    goBackMap.put("orderAudit", orderAudit);
    goBackMap.put("activity_out_date", "false");
    goBackMap.put("finance_info_ok", "true");
    goBackMap.put("biz_mode", "1");
    afterGoBack =
        workflowAccessor.completeTaskInstance(afterGoBack.get(0), "GoBackIsFalseTest", goBackMap);
    extendAttributes = workflowAccessor.getTaskInstanceInformations(afterGoBack.get(0));
    Assert.assertEquals(
        "agt_manageraudit",
        extendAttributes.get(WorkflowOperations.TaskInformations.TASK_TAG.name()));
    goBackMap = new HashMap<String, Object>();
    orderAudit.setAuditAction(DummyOrderAudit.REJECT);
    goBackMap.put("orderAudit", orderAudit);
    goBackMap.put("need_highlevel_audit", "false");
    afterGoBack =
        workflowAccessor.completeTaskInstance(afterGoBack.get(0), "bizModeRejectTest", goBackMap);
    extendAttributes = workflowAccessor.getTaskInstanceInformations(afterGoBack.get(0));
    Assert.assertEquals(
        "completefinanceinfo",
        extendAttributes.get(WorkflowOperations.TaskInformations.TASK_TAG.name()));

    // -------------------------------- Test extend mappings
    activitiAccessor.runExtraCommand(
        new Command<Void>() {

          @Override
          public Void execute(CommandContext commandContext) {
            Date[] startAndEndDate = org.rill.utils.DateUtils.getDayStartAndEndDate(new Date());
            Map<String, Object> parameterMap = new HashMap<String, Object>();
            parameterMap.put("timeBegin", startAndEndDate[0]);
            parameterMap.put("timeEnd", startAndEndDate[1]);
            Object runningResult =
                commandContext
                    .getDbSqlSession()
                    .selectOne("selectDayRunningRootHistoricProcessInstanceCnt", parameterMap);
            Assert.assertEquals(1L, runningResult);
            return null;
          }
        });
    // -------------------------------- Retrieve chart informations
    Map<String, ChartInfo> allChartInfos =
        getProcessMonitorChartInfoHelper().getMonitorChartInfo(processInstanceId);
    //		Assert.assertEquals(5, allChartInfos.size());

    for (Entry<String, ChartInfo> entry : allChartInfos.entrySet()) {
      try {
        File tmpImage = File.createTempFile("processDefinitionKey" + entry.getKey(), ".png");
        FileImageOutputStream fios = new FileImageOutputStream(tmpImage);
        fios.write(entry.getValue().getDiagramBytes());
        fios.flush();
        fios.close();
        fios = null;
      } catch (IOException ex) {
        logger.error("Exception occurred when try to generate png", ex);
        Assert.assertEquals(
            "Can not generate process " + entry.getKey() + " diagram image.", true, false);
      }
    }
  }
 /**
  * Convert historic process instances to BPMN process instances
  *
  * @param historicProcessInstanceList List of historic process instances
  * @return BPMNProcessInstance array
  */
 private BPMNProcessInstance[] getBPMNProcessInstances(
     List<HistoricProcessInstance> historicProcessInstanceList) {
   BPMNProcessInstance bpmnProcessInstance;
   List<BPMNProcessInstance> bpmnProcessInstances = new ArrayList<>();
   for (HistoricProcessInstance instance : historicProcessInstanceList) {
     bpmnProcessInstance = new BPMNProcessInstance();
     bpmnProcessInstance.setProcessDefinitionId(instance.getProcessDefinitionId());
     bpmnProcessInstance.setTenantId(instance.getTenantId());
     bpmnProcessInstance.setName(instance.getName());
     bpmnProcessInstance.setInstanceId(instance.getId());
     bpmnProcessInstance.setBusinessKey(instance.getBusinessKey());
     bpmnProcessInstance.setStartTime(instance.getStartTime());
     bpmnProcessInstance.setEndTime(instance.getEndTime());
     bpmnProcessInstance.setDuration(instance.getDurationInMillis());
     bpmnProcessInstance.setStartUserId(instance.getStartUserId());
     bpmnProcessInstance.setStartActivityId(instance.getStartActivityId());
     bpmnProcessInstance.setVariables(formatVariables(instance.getProcessVariables()));
     bpmnProcessInstances.add(bpmnProcessInstance);
   }
   return bpmnProcessInstances.toArray(new BPMNProcessInstance[bpmnProcessInstances.size()]);
 }
  /**
   * 流程列表
   *
   * @param user 操作用户
   * @param processStatus 流程状态 unfinished finished involve
   * @param searchable
   * @param model
   * @return
   */
  @RequestMapping(method = RequestMethod.GET)
  public String list(
      @CurrentUser User user,
      @RequestParam("processstatus") String processStatus,
      Searchable searchable,
      Model model) {

    //		if (permissionList != null) {
    //			this.permissionList.assertHasViewPermission();
    //		}

    if (null != processStatus && "involve".equals(processStatus)) {

      Page<HistoricProcessInstance> processInstances =
          userProcessService.findInvolvedProcessInstances(user.getUsername(), searchable.getPage());
      Map<String, BpmProcess> processMap = new HashMap<String, BpmProcess>();
      for (HistoricProcessInstance processInstance : processInstances) {
        String processDefinitionId = processInstance.getProcessDefinitionId();
        BpmProcess bpmProcess =
            bpmProcessService.findByBpmConfBase(
                bpmConfBaseService.findByProcessDefinitionId(processDefinitionId));
        if (!processMap.containsKey(processDefinitionId)) {
          processMap.put(processDefinitionId, bpmProcess);
        }
      }
      model.addAttribute("bpmProcessMap", processMap);
      model.addAttribute("page", processInstances);
    } else if (null != processStatus && "unfinished".equals(processStatus)) {
      Page<HistoricProcessInstance> processInstances =
          userProcessService.findRunningProcessInstances(user.getUsername(), searchable.getPage());
      Map<String, BpmProcess> processMap = new HashMap<String, BpmProcess>();
      for (HistoricProcessInstance processInstance : processInstances) {
        String processDefinitionId = processInstance.getProcessDefinitionId();
        BpmProcess bpmProcess =
            bpmProcessService.findByBpmConfBase(
                bpmConfBaseService.findByProcessDefinitionId(processDefinitionId));
        if (!processMap.containsKey(processDefinitionId)) {
          processMap.put(processDefinitionId, bpmProcess);
        }
      }
      model.addAttribute("bpmProcessMap", processMap);
      model.addAttribute("page", processInstances);
    } else if (null != processStatus && "finished".equals(processStatus)) {
      Page<HistoricProcessInstance> processInstances =
          userProcessService.findCompletedProcessInstances(
              user.getUsername(), searchable.getPage());
      Map<String, BpmProcess> processMap = new HashMap<String, BpmProcess>();
      for (HistoricProcessInstance processInstance : processInstances) {
        String processDefinitionId = processInstance.getProcessDefinitionId();
        BpmProcess bpmProcess =
            bpmProcessService.findByBpmConfBase(
                bpmConfBaseService.findByProcessDefinitionId(processDefinitionId));
        if (!processMap.containsKey(processDefinitionId)) {
          processMap.put(processDefinitionId, bpmProcess);
        }
      }
      model.addAttribute("bpmProcessMap", processMap);
      model.addAttribute("page", processInstances);
    }
    if (listAlsoSetCommonData) {
      setCommonData(model);
    }

    return "bpm/userprocess/list";
  }
  public InputStream generateDiagram(String processInstanceId) throws IOException {
    HistoricProcessInstance historicProcessInstance =
        Context.getCommandContext()
            .getHistoricProcessInstanceEntityManager()
            .findHistoricProcessInstance(processInstanceId);
    String processDefinitionId = historicProcessInstance.getProcessDefinitionId();
    GetBpmnModelCmd getBpmnModelCmd = new GetBpmnModelCmd(processDefinitionId);
    BpmnModel bpmnModel = getBpmnModelCmd.execute(Context.getCommandContext());
    Point point = getMinXAndMinY(bpmnModel);
    this.minX = point.x;
    this.minY = point.y;
    this.minX = (this.minX <= 5) ? 5 : this.minX;
    this.minY = (this.minY <= 5) ? 5 : this.minY;
    this.minX -= 5;
    this.minY -= 5;

    ProcessDefinitionEntity definition =
        new GetDeploymentProcessDefinitionCmd(processDefinitionId)
            .execute(Context.getCommandContext());
    String diagramResourceName = definition.getDiagramResourceName();
    String deploymentId = definition.getDeploymentId();
    byte[] bytes =
        Context.getCommandContext()
            .getResourceEntityManager()
            .findResourceByDeploymentIdAndResourceName(deploymentId, diagramResourceName)
            .getBytes();
    InputStream originDiagram = new ByteArrayInputStream(bytes);
    BufferedImage image = ImageIO.read(originDiagram);

    HistoricActivityInstanceQueryImpl historicActivityInstanceQueryImpl =
        new HistoricActivityInstanceQueryImpl();
    historicActivityInstanceQueryImpl
        .processInstanceId(processInstanceId)
        .orderByHistoricActivityInstanceStartTime()
        .asc();

    Page page = new Page(0, 100);
    List<HistoricActivityInstance> activityInstances =
        Context.getCommandContext()
            .getHistoricActivityInstanceEntityManager()
            .findHistoricActivityInstancesByQueryCriteria(historicActivityInstanceQueryImpl, page);

    this.drawHistoryFlow(image, processInstanceId);

    for (HistoricActivityInstance historicActivityInstance : activityInstances) {
      String historicActivityId = historicActivityInstance.getActivityId();
      ActivityImpl activity = definition.findActivity(historicActivityId);

      if (activity != null) {
        if (historicActivityInstance.getEndTime() == null) {
          // 节点正在运行中
          signRunningNode(
              image,
              activity.getX() - this.minX,
              activity.getY() - this.minY,
              activity.getWidth(),
              activity.getHeight(),
              historicActivityInstance.getActivityType());
        } else {
          String deleteReason = null;

          if (historicActivityInstance.getTaskId() != null) {
            deleteReason =
                Context.getCommandContext()
                    .getHistoricTaskInstanceEntityManager()
                    .findHistoricTaskInstanceById(historicActivityInstance.getTaskId())
                    .getDeleteReason();
          }

          // 节点已经结束
          if ("跳过".equals(deleteReason)) {
            signSkipNode(
                image,
                activity.getX() - this.minX,
                activity.getY() - this.minY,
                activity.getWidth(),
                activity.getHeight(),
                historicActivityInstance.getActivityType());
          } else {
            signHistoryNode(
                image,
                activity.getX() - this.minX,
                activity.getY() - this.minY,
                activity.getWidth(),
                activity.getHeight(),
                historicActivityInstance.getActivityType());
          }
        }
      }
    }

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    String formatName = getDiagramExtension(diagramResourceName);
    ImageIO.write(image, formatName, out);

    return new ByteArrayInputStream(out.toByteArray());
  }