diff --git a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceActionQueueDao.java b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceActionQueueDao.java index 72bf6702be..6095204e34 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceActionQueueDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceActionQueueDao.java @@ -1,8 +1,11 @@ package org.finos.waltz.data.survey; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.finos.waltz.common.DateTimeUtilities; import org.finos.waltz.model.survey.ImmutableSurveyInstanceActionQueueItem; import org.finos.waltz.model.survey.SurveyInstanceAction; +import org.finos.waltz.model.survey.SurveyInstanceActionParams; import org.finos.waltz.model.survey.SurveyInstanceActionQueueItem; import org.finos.waltz.model.survey.SurveyInstanceActionStatus; import org.finos.waltz.model.survey.SurveyInstanceStatus; @@ -19,9 +22,11 @@ import java.sql.Timestamp; import java.util.List; +import java.util.Optional; import static java.lang.String.format; import static java.util.Optional.ofNullable; +import static org.finos.waltz.common.JacksonUtilities.getJsonMapper; import static org.finos.waltz.schema.Tables.SURVEY_INSTANCE_ACTION_QUEUE; @Repository @@ -30,12 +35,16 @@ public class SurveyInstanceActionQueueDao { private final DSLContext dsl; public static final RecordMapper TO_DOMAIN_MAPPER = r -> { + SurveyInstanceActionQueueRecord record = r.into(SURVEY_INSTANCE_ACTION_QUEUE); + + Optional surveyInstanceActionParams = readParams(getJsonMapper(), record.getActionParams()); + return ImmutableSurveyInstanceActionQueueItem.builder() .id(record.getId()) .action(SurveyInstanceAction.valueOf(record.getAction())) .surveyInstanceId(record.getSurveyInstanceId()) - .actionParams(record.getActionParams()) + .actionParams(surveyInstanceActionParams) .initialState(SurveyInstanceStatus.valueOf(record.getInitialState())) .submittedAt(DateTimeUtilities.toLocalDateTime(record.getSubmittedAt())) .submittedBy(record.getSubmittedBy()) @@ -47,6 +56,19 @@ public class SurveyInstanceActionQueueDao { }; + private static Optional readParams(ObjectMapper jsonMapper, String actionParams) { + if(actionParams == null) { + return Optional.empty(); + } else { + try { + return Optional.ofNullable(jsonMapper.readValue(actionParams, SurveyInstanceActionParams.class)); + } catch (JsonProcessingException e) { + return Optional.empty(); + } + } + } + + @Autowired SurveyInstanceActionQueueDao(DSLContext dsl) { this.dsl = dsl; diff --git a/waltz-integration-test/src/test/java/org/finos/waltz/integration_test/inmem/service/SurveyInstanceActionQueueTest.java b/waltz-integration-test/src/test/java/org/finos/waltz/integration_test/inmem/service/SurveyInstanceActionQueueTest.java index 2513ef3221..a082066ad8 100644 --- a/waltz-integration-test/src/test/java/org/finos/waltz/integration_test/inmem/service/SurveyInstanceActionQueueTest.java +++ b/waltz-integration-test/src/test/java/org/finos/waltz/integration_test/inmem/service/SurveyInstanceActionQueueTest.java @@ -1,13 +1,17 @@ package org.finos.waltz.integration_test.inmem.service; +import com.fasterxml.jackson.core.JsonProcessingException; import org.finos.waltz.common.DateTimeUtilities; +import org.finos.waltz.common.JacksonUtilities; import org.finos.waltz.common.exception.InsufficientPrivelegeException; import org.finos.waltz.integration_test.inmem.BaseInMemoryIntegrationTest; import org.finos.waltz.model.EntityKind; import org.finos.waltz.model.EntityReference; import org.finos.waltz.model.IdSelectionOptions; import org.finos.waltz.model.ReleaseLifecycleStatus; +import org.finos.waltz.model.changelog.ChangeLog; import org.finos.waltz.model.survey.ImmutableInstancesAndRecipientsCreateCommand; +import org.finos.waltz.model.survey.ImmutableSurveyInstanceActionParams; import org.finos.waltz.model.survey.ImmutableSurveyQuestionResponse; import org.finos.waltz.model.survey.ImmutableSurveyRunCreateCommand; import org.finos.waltz.model.survey.InstancesAndRecipientsCreateCommand; @@ -18,6 +22,7 @@ import org.finos.waltz.model.survey.SurveyInstanceStatus; import org.finos.waltz.model.survey.SurveyIssuanceKind; import org.finos.waltz.model.survey.SurveyQuestionResponse; +import org.finos.waltz.service.changelog.ChangeLogService; import org.finos.waltz.service.survey.SurveyInstanceActionQueueService; import org.finos.waltz.service.survey.SurveyInstanceService; import org.finos.waltz.service.survey.SurveyRunService; @@ -32,18 +37,22 @@ import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; import java.util.Set; -import static java.lang.String.format; import static java.util.Collections.emptySet; +import static org.finos.waltz.common.CollectionUtilities.any; import static org.finos.waltz.common.CollectionUtilities.find; import static org.finos.waltz.common.DateTimeUtilities.nowUtcTimestamp; import static org.finos.waltz.common.DateTimeUtilities.toLocalDate; +import static org.finos.waltz.model.EntityReference.mkRef; import static org.finos.waltz.test_common.helpers.NameHelper.mkName; @Service public class SurveyInstanceActionQueueTest extends BaseInMemoryIntegrationTest { + public static final String REASON_TEXT = "test reason to capture"; + @Autowired private AppHelper appHelper; @@ -68,6 +77,9 @@ public class SurveyInstanceActionQueueTest extends BaseInMemoryIntegrationTest { @Autowired private InvolvementHelper involvementHelper; + @Autowired + private ChangeLogService changeLogService; + @Test public void processActionsCanSubmitSurveys() throws InsufficientPrivelegeException { String username = mkName("submitSurvey"); @@ -306,7 +318,32 @@ public void processActionsCanDoAllActions() throws InsufficientPrivelegeExceptio Assertions.assertEquals(SurveyInstanceActionStatus.SUCCESS, submit.status()); // Approve - Long approvalId = actionQueueHelper.addActionToQueue(instance.id().get(), SurveyInstanceAction.APPROVING, "reason", SurveyInstanceStatus.COMPLETED, username); + Long approvalId = actionQueueHelper.addActionToQueue(instance.id().get(), SurveyInstanceAction.APPROVING, null, SurveyInstanceStatus.COMPLETED, username); + actionQueueService.performActions(); + + SurveyInstance postApproval = instanceService.getById(instance.id().get()); + Assertions.assertEquals(SurveyInstanceStatus.APPROVED, postApproval.status(), "Action should be marked 'approved'"); + + SurveyInstanceActionQueueItem approval = actionQueueService.getById(approvalId); + Assertions.assertEquals(SurveyInstanceActionStatus.SUCCESS, approval.status()); + } + + + @Test + public void processActionsAbleToParseReasonFromAction() throws InsufficientPrivelegeException { + String username = mkName("reason"); + SurveyInstance instance = setupSurvey("reason", username); + + actionQueueHelper.addActionToQueue(instance.id().get(), SurveyInstanceAction.SUBMITTING, null, SurveyInstanceStatus.NOT_STARTED, username); + + ImmutableSurveyInstanceActionParams reasonParams = ImmutableSurveyInstanceActionParams + .builder() + .reason(REASON_TEXT) + .build(); + + String reason = mkReasonString(reasonParams); + + Long approvalId = actionQueueHelper.addActionToQueue(instance.id().get(), SurveyInstanceAction.APPROVING, reason, SurveyInstanceStatus.COMPLETED, username); actionQueueService.performActions(); SurveyInstance postApproval = instanceService.getById(instance.id().get()); @@ -314,6 +351,17 @@ public void processActionsCanDoAllActions() throws InsufficientPrivelegeExceptio SurveyInstanceActionQueueItem approval = actionQueueService.getById(approvalId); Assertions.assertEquals(SurveyInstanceActionStatus.SUCCESS, approval.status()); + + List changeLogs = changeLogService.findByParentReference(mkRef(EntityKind.SURVEY_INSTANCE, postApproval.id().get()), Optional.empty(), Optional.empty()); + Assertions.assertTrue(any(changeLogs, d -> d.message().contains(REASON_TEXT)), "Reason should be captured in the change log"); + } + + private String mkReasonString(ImmutableSurveyInstanceActionParams reason) { + try { + return JacksonUtilities.getJsonMapper().writeValueAsString(reason); + } catch (JsonProcessingException e) { + return null; + } } @@ -335,7 +383,7 @@ private SurveyInstance setupSurvey(String nameStem, String username, boolean pop long invKindId = involvementHelper.mkInvolvementKind(mkName("invKind")); involvementHelper.createInvolvement(personId, invKindId, a1); - ImmutableSurveyRunCreateCommand runCmd = mkRunCommand(templateId, EntityReference.mkRef(EntityKind.ORG_UNIT, ouIds.a), invKindId); + ImmutableSurveyRunCreateCommand runCmd = mkRunCommand(templateId, mkRef(EntityKind.ORG_UNIT, ouIds.a), invKindId); Long runId = runService.createSurveyRun(username, runCmd).id().get(); InstancesAndRecipientsCreateCommand createCmd = mkInstancesRecipCreateCmd(runId); diff --git a/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceActionParams.java b/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceActionParams.java new file mode 100644 index 0000000000..5812b442b2 --- /dev/null +++ b/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceActionParams.java @@ -0,0 +1,16 @@ +package org.finos.waltz.model.survey; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value; + +import java.util.Optional; + +@Value.Immutable +@JsonSerialize(as = ImmutableSurveyInstanceActionParams.class) +@JsonDeserialize(as = ImmutableSurveyInstanceActionParams.class) +public abstract class SurveyInstanceActionParams { + + public abstract Optional reason(); + +} diff --git a/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceActionQueueItem.java b/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceActionQueueItem.java index 973cb49994..d5c670751c 100644 --- a/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceActionQueueItem.java +++ b/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceActionQueueItem.java @@ -5,14 +5,14 @@ import org.immutables.value.Value; import java.time.LocalDateTime; +import java.util.Optional; @Value.Immutable public abstract class SurveyInstanceActionQueueItem implements IdProvider { public abstract SurveyInstanceAction action(); public abstract Long surveyInstanceId(); - @Nullable - public abstract String actionParams(); + public abstract Optional actionParams(); public abstract SurveyInstanceStatus initialState(); public abstract LocalDateTime submittedAt(); public abstract String submittedBy(); diff --git a/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceActionQueueService.java b/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceActionQueueService.java index ed83dbdc90..0debf08036 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceActionQueueService.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceActionQueueService.java @@ -4,6 +4,7 @@ import org.finos.waltz.data.survey.SurveyInstanceActionQueueDao; import org.finos.waltz.model.survey.ImmutableSurveyInstanceStatusChangeCommand; import org.finos.waltz.model.survey.SurveyInstance; +import org.finos.waltz.model.survey.SurveyInstanceActionParams; import org.finos.waltz.model.survey.SurveyInstanceActionQueueItem; import org.finos.waltz.model.survey.SurveyInstanceActionStatus; import org.finos.waltz.model.survey.SurveyInstanceStatus; @@ -26,6 +27,7 @@ public class SurveyInstanceActionQueueService { private final SurveyInstanceService surveyInstanceService; private final DSLContext dslContext; + @Autowired SurveyInstanceActionQueueService(SurveyInstanceActionQueueDao surveyInstanceActionQueueDao, SurveyInstanceService surveyInstanceService, @@ -90,10 +92,11 @@ public void performActions() { String username = action.submittedBy(); + Optional reason = action.actionParams().map(SurveyInstanceActionParams::reason).orElse(Optional.empty()); ImmutableSurveyInstanceStatusChangeCommand updateCmd = ImmutableSurveyInstanceStatusChangeCommand .builder() .action(action.action()) - .reason(Optional.ofNullable(action.actionParams())) + .reason(reason) .build(); try {