diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ChangePlanItemStateCmd.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ChangePlanItemStateCmd.java index 26aeb8e9f40..88161b1cbef 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ChangePlanItemStateCmd.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ChangePlanItemStateCmd.java @@ -38,7 +38,9 @@ public ChangePlanItemStateCmd(ChangePlanItemStateBuilderImpl changePlanItemState public Void execute(CommandContext commandContext) { if (changePlanItemStateBuilder.getActivatePlanItemDefinitions().size() == 0 && changePlanItemStateBuilder.getTerminatePlanItemDefinitions().size() == 0 && - changePlanItemStateBuilder.getChangeToAvailableStatePlanItemDefinitions().size() == 0) { + changePlanItemStateBuilder.getChangeToAvailableStatePlanItemDefinitions().size() == 0 && + changePlanItemStateBuilder.getWaitingForRepetitionPlanItemDefinitions().size() == 0 && + changePlanItemStateBuilder.getRemoveWaitingForRepetitionPlanItemDefinitions().size() == 0) { throw new FlowableIllegalArgumentException("No move plan item instance or (activate) plan item definition ids provided"); diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/DefaultCmmnDynamicStateManager.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/DefaultCmmnDynamicStateManager.java index 74f4a11028f..07e20172645 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/DefaultCmmnDynamicStateManager.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/DefaultCmmnDynamicStateManager.java @@ -40,6 +40,8 @@ public void movePlanItemInstanceState(ChangePlanItemStateBuilderImpl changePlanI .setActivatePlanItemDefinitions(changePlanItemStateBuilder.getActivatePlanItemDefinitions()) .setTerminatePlanItemDefinitions(changePlanItemStateBuilder.getTerminatePlanItemDefinitions()) .setChangePlanItemDefinitionsToAvailable(changePlanItemStateBuilder.getChangeToAvailableStatePlanItemDefinitions()) + .setWaitingForRepetitionPlanItemDefinitions(changePlanItemStateBuilder.getWaitingForRepetitionPlanItemDefinitions()) + .setRemoveWaitingForRepetitionPlanItemDefinitions(changePlanItemStateBuilder.getRemoveWaitingForRepetitionPlanItemDefinitions()) .setCaseVariables(changePlanItemStateBuilder.getCaseVariables()) .setChildInstanceTaskVariables(changePlanItemStateBuilder.getChildInstanceTaskVariables()); diff --git a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/dynamic/ChangeStateTest.java b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/dynamic/ChangeStateTest.java index ee2659f65f6..ce4b582ffe8 100644 --- a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/dynamic/ChangeStateTest.java +++ b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/dynamic/ChangeStateTest.java @@ -139,4 +139,57 @@ public void testChangeHumanTaskFromStage() { assertCaseInstanceEnded(caseInstance); } + + @Test + @CmmnDeployment + public void testChangeHumanTaskRepetition() { + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("myCase").start(); + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(task.getName()).isEqualTo("Task One"); + + cmmnTaskService.complete(task.getId()); + + cmmnRuntimeService.createChangePlanItemStateBuilder() + .caseInstanceId(caseInstance.getId()) + .addWaitingForRepetitionPlanItemDefinitionId("task2") + .changeState(); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery().caseInstanceId(caseInstance.getId()).includeEnded().list(); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsExactlyInAnyOrder(PlanItemInstanceState.COMPLETED, PlanItemInstanceState.ACTIVE, PlanItemInstanceState.WAITING_FOR_REPETITION); + + task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(task.getName()).isEqualTo("Task Two"); + + cmmnRuntimeService.createChangePlanItemStateBuilder() + .caseInstanceId(caseInstance.getId()) + .activatePlanItemDefinitionId("task1") + .changeState(); + + cmmnTaskService.complete(task.getId()); + + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery().caseInstanceId(caseInstance.getId()).includeEnded().list(); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsExactlyInAnyOrder(PlanItemInstanceState.COMPLETED, PlanItemInstanceState.COMPLETED, PlanItemInstanceState.ACTIVE, PlanItemInstanceState.WAITING_FOR_REPETITION); + + cmmnRuntimeService.createChangePlanItemStateBuilder() + .caseInstanceId(caseInstance.getId()) + .addRemoveWaitingForRepetitionPlanItemDefinitionId("task2") + .changeState(); + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery().caseInstanceId(caseInstance.getId()).includeEnded().list(); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsExactlyInAnyOrder(PlanItemInstanceState.COMPLETED, PlanItemInstanceState.COMPLETED, PlanItemInstanceState.ACTIVE); + + task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(task.getName()).isEqualTo("Task One"); + + cmmnTaskService.complete(task.getId()); + + assertCaseInstanceEnded(caseInstance); + } } diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/dynamic/ChangeStateTest.testChangeHumanTaskRepetition.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/dynamic/ChangeStateTest.testChangeHumanTaskRepetition.cmmn new file mode 100644 index 00000000000..165770d18c8 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/dynamic/ChangeStateTest.testChangeHumanTaskRepetition.cmmn @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + complete + + + + + + + + + +