Skip to content

Commit

Permalink
MID-9533: fix closing approval case with 'skip' outcome for last stage
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Apr 24, 2024
1 parent dce6fcd commit 2814959
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,14 @@ public void populateItem(Item<ICellPopulator<PrismContainerValueWrapper<CaseWork

Component c = cellItem.get(componentId);

PrismReferenceValue refVal = caseType.getObjectRef().asReferenceValue();
String descriptionValue = refVal.getObject() != null ?
refVal.getObject().asObjectable().getDescription() : "";
String descriptionValue = "";
ObjectReferenceType objectRef = caseType.getObjectRef();
if (objectRef != null) {
PrismReferenceValue refVal = objectRef.asReferenceValue();
if (refVal.getObject() != null) {
descriptionValue = refVal.getObject().asObjectable().getDescription();
}
}

c.add(new AttributeAppender("title", descriptionValue));
}
Expand Down Expand Up @@ -823,6 +828,10 @@ public void onClick(AjaxRequestTarget target, IModel<SelectableBean<CaseType>> r
@Override
public boolean isEnabled(IModel<SelectableBean<CaseType>> rowModel) {
CaseType caseType = rowModel.getObject().getValue();
if (caseType.getObjectRef() == null) {
return false;
}

PrismObject object = caseType.getObjectRef().getObject();
// Do not generate link if the object has not been created yet.
// Check the version to see if it has not been created.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ public interface StageClosingResult extends DebugDumpable {

boolean shouldCaseProcessingContinue();

/** URI to be used as the final case outcome (if this stage closing means closing the whole case). */
@Nullable String getCaseOutcomeUri();

@NotNull String getStageOutcomeUri();

@Nullable AutomatedCompletionReasonType getAutomatedStageCompletionReason();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ class CloseStageAction extends InternalAction {
return new OpenStageAction(operation);
} else {
// Result of the last stage is the result of the whole case
return new CloseCaseAction(operation, closingInformation.getStageOutcomeUri());
return new CloseCaseAction(operation, closingInformation.getCaseOutcomeUri());
}
}

private void recordAutoCompletionToCaseHistory() {
assert autoClosingInformation != null;
StageCompletionEventType event = new StageCompletionEventType(beans.prismContext);
StageCompletionEventType event = new StageCompletionEventType();
event.setTimestamp(beans.clock.currentTimeXMLGregorianCalendar());
event.setStageNumber(operation.getCurrentStageNumber());
event.setAutomatedDecisionReason(autoClosingInformation.getAutomatedStageCompletionReason());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public boolean shouldCaseProcessingContinue() {
return false;
}

@Override
public @Nullable String getCaseOutcomeUri() {
return stageOutcomeUri; // Normally (for everything except approvals) these are the same.
}

@Override
public @NotNull String getStageOutcomeUri() {
return stageOutcomeUri;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public StageClosingResult process() {
return new StageClosingResultImpl(
shouldContinue,
ApprovalUtils.toUri(shouldContinue),
ApprovalUtils.toUri(shouldContinue),
null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,30 @@
public class StageClosingResultImpl implements StageClosingResult {

private final boolean shouldProcessingContinue;
@NotNull private final String outcomeUri;
@Nullable private final String caseOutcomeUri;
@NotNull private final String stageOutcomeUri;

// TODO - this is approval-specific!
@Nullable private final AutomatedCompletionReasonType automatedCompletionReason;

public StageClosingResultImpl(
boolean shouldProcessingContinue,
@NotNull String outcomeUri,
@Nullable String caseOutcomeUri,
@NotNull String stageOutcomeUri,
@Nullable AutomatedCompletionReasonType automatedCompletionReason) {
this.shouldProcessingContinue = shouldProcessingContinue;
this.outcomeUri = outcomeUri;
this.caseOutcomeUri = caseOutcomeUri;
this.stageOutcomeUri = stageOutcomeUri;
this.automatedCompletionReason = automatedCompletionReason;
}

@Override
public @NotNull String getStageOutcomeUri() {
return outcomeUri;
return stageOutcomeUri;
}

@Override
public @Nullable String getCaseOutcomeUri() {
return caseOutcomeUri;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.AutomatedCompletionReasonType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;

import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemOutcomeType;

import org.jetbrains.annotations.NotNull;

import java.util.Set;
Expand Down Expand Up @@ -48,8 +50,14 @@ public boolean noApproversFound() {

public StageClosingResult createStageClosingInformation() {
if (predeterminedOutcome != null) {
WorkItemOutcomeType caseOutcome =
switch (predeterminedOutcome) {
case APPROVE, SKIP -> WorkItemOutcomeType.APPROVE;
case REJECT -> WorkItemOutcomeType.REJECT;
};
return new StageClosingResultImpl(
shouldProcessingContinue(predeterminedOutcome),
ApprovalUtils.toUri(caseOutcome),
ApprovalUtils.toUri(predeterminedOutcome),
automatedCompletionReason);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ public class TestMiscellaneous extends AbstractWfTestPolicy {
TEST_DIR, "role-approved-by-multiple-relations.xml", "62d7fcdf-92b0-4c49-ae40-33b0a814ed56");
private static final TestObject<UserType> USER_APPROVER_BY_MULTIPLE_RELATIONS = TestObject.file(
TEST_DIR, "user-approver-by-multiple-relations.xml", "a9aca7bb-923e-4be6-9aa4-5c90af978207");
private static final TestObject<RoleType> ROLE_APPROVE_WITH_SKIP_LAST_STAGE = TestObject.file(
TEST_DIR, "role-approve-with-skip-last-stage.xml", "8b928d45-bb91-4a02-8418-6ae0d3b6a1d3");

@Override
protected PrismObject<UserType> getDefaultActor() {
Expand Down Expand Up @@ -137,6 +139,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
ROLE_APPROVED_BY_ORG.init(this, initTask, initResult);
ROLE_APPROVED_BY_MULTIPLE_RELATIONS.init(this, initTask, initResult);
USER_APPROVER_BY_MULTIPLE_RELATIONS.init(this, initTask, initResult);

ROLE_APPROVE_WITH_SKIP_LAST_STAGE.init(this, initTask, initResult);
}

@Test
Expand Down Expand Up @@ -960,6 +964,46 @@ public void test420SeparateRelationQueries() throws Exception {
.assertRole(ROLE_APPROVED_BY_MULTIPLE_RELATIONS.oid);
}

@Test
public void test430ApproveWithSkipLastStage() throws Exception {
Task task = getTestTask();
OperationResult result = task.getResult();
login(userAdministrator);

when("a user with role assignment is created");
String name = "test430";
UserType user = new UserType()
.name(name)
.assignment(ROLE_APPROVE_WITH_SKIP_LAST_STAGE.assignmentTo());

// setTracing(task, createDefaultTracingProfile()); // just to get the whole operation result
addObject(user, task, result);

then("user is not created but case exists");
assertNoUserByUsername(name);
var workItem = assertCase(result, "after")
.display()
.subcases()
.assertSubcases(2)
.singleWithoutApprovalSchema().display().end() // user ADD
.singleWithApprovalSchema() // assignment ADD
.display()
.workItems()
.single()
.assertAssignees(userAdministrator.getOid())
.getRealValue();

when("work item is approved");
approveWorkItem(workItem, task, result);

@NotNull CaseType caseBean = CaseTypeUtil.getCaseRequired(workItem);
waitForCaseClose(caseBean);

then("user with assignment exists");
assertCase(getCase(caseBean.getOid()), "case")
.assertApproved();
}

private void checkNoMultiRelationsOrFilter(TraceType t) {
if (!(t instanceof RepositorySearchObjectsTraceType)) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!--
~ Copyright (c) 2010-2019 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<role oid="8b928d45-bb91-4a02-8418-6ae0d3b6a1d3">
<name>role-approve-with-skip-last-stage</name>
<assignment>
<policyRule>
<name>skip-2-stage</name>
<policyConstraints>
<assignment>
<operation>add</operation>
<operation>modify</operation>
</assignment>
</policyConstraints>
<policyActions>
<approval>
<compositionStrategy>
<order>20</order>
</compositionStrategy>
<approvalSchema>
<stage>
<name>Stage 1</name>
<evaluationStrategy>firstDecides</evaluationStrategy>
<approverRef oid="00000000-0000-0000-0000-000000000002" relation="default" type="UserType"/>
</stage>
</approvalSchema>
</approval>
<approval>
<compositionStrategy>
<order>30</order>
</compositionStrategy>
<approvalSchema>
<stage>
<name>Stage 2</name>
<outcomeIfNoApprovers>skip</outcomeIfNoApprovers>
</stage>
</approvalSchema>
</approval>
</policyActions>

</policyRule>
<activation>
<effectiveStatus>enabled</effectiveStatus>
</activation>
</assignment>
</role>

0 comments on commit 2814959

Please sign in to comment.