diff --git a/waltz-data/src/main/java/org/finos/waltz/data/involvement/InvolvementDao.java b/waltz-data/src/main/java/org/finos/waltz/data/involvement/InvolvementDao.java index 26b1908c94..6d6c48eee4 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/involvement/InvolvementDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/involvement/InvolvementDao.java @@ -177,7 +177,8 @@ public List findAllByEmployeeId(String employeeId) { public List findPeopleByEntityReference(EntityReference ref) { - return dsl.selectDistinct(PERSON.fields()) + return dsl + .selectDistinct(PERSON.fields()) .from(PERSON) .innerJoin(INVOLVEMENT) .on(INVOLVEMENT.ENTITY_ID.eq(ref.id())) diff --git a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceDao.java b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceDao.java index 6272c09863..66f41c9d76 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceDao.java @@ -316,10 +316,12 @@ public int deleteForSurveyRun(long surveyRunId) { public int updateStatus(long instanceId, SurveyInstanceStatus newStatus) { checkNotNull(newStatus, "newStatus cannot be null"); - return dsl.update(si) + return dsl + .update(si) .set(si.STATUS, newStatus.name()) .where(si.STATUS.notEqual(newStatus.name()) - .and(si.ID.eq(instanceId))) + .and(si.ID.eq(instanceId)) + .and(si.ORIGINAL_INSTANCE_ID.isNull())) .execute(); } @@ -366,13 +368,19 @@ public int updateOwningRoleForSurveyRun(long surveyRunId, String role) { } - public int updateSubmitted(long instanceId, String userName) { + public int markSubmitted(long instanceId, String userName) { checkNotNull(userName, "userName cannot be null"); - return dsl.update(si) + return dsl + .update(si) + .set(si.STATUS, SurveyInstanceStatus.COMPLETED.name()) .set(si.SUBMITTED_AT, Timestamp.valueOf(nowUtc())) .set(si.SUBMITTED_BY, userName) - .where(si.ID.eq(instanceId)) + .where(si.ID.eq(instanceId) + .and(si.ORIGINAL_INSTANCE_ID.isNull()) + .and(si.STATUS.in( + SurveyInstanceStatus.NOT_STARTED.name(), + SurveyInstanceStatus.IN_PROGRESS.name()))) .execute(); } @@ -380,20 +388,33 @@ public int updateSubmitted(long instanceId, String userName) { public int markApproved(long instanceId, String userName) { checkNotNull(userName, "userName cannot be null"); - return dsl.update(si) + return dsl + .update(si) .set(si.APPROVED_AT, Timestamp.valueOf(nowUtc())) .set(si.APPROVED_BY, userName) .set(si.STATUS, SurveyInstanceStatus.APPROVED.name()) - .where(si.ID.eq(instanceId)) + .where(si.ID.eq(instanceId) + .and(si.ORIGINAL_INSTANCE_ID.isNull()) + .and(si.STATUS.eq(SurveyInstanceStatus.COMPLETED.name()))) .execute(); } - public void clearApproved(long instanceId) { - dsl.update(si) + public int reopenSurvey(long instanceId) { + return dsl + .update(si) + .set(si.STATUS, SurveyInstanceStatus.IN_PROGRESS.name()) .set(si.APPROVED_AT, (Timestamp) null) .set(si.APPROVED_BY, (String) null) - .where(si.ID.eq(instanceId)) + .set(si.SUBMITTED_AT, (Timestamp) null) + .set(si.SUBMITTED_BY, (String) null) + .set(si.ISSUED_ON, toSqlDate(nowUtcTimestamp())) //update the issued on to the current date + .where(si.ID.eq(instanceId) + .and(si.ORIGINAL_INSTANCE_ID.isNull()) + .and(si.STATUS.in( + SurveyInstanceStatus.APPROVED.name(), + SurveyInstanceStatus.REJECTED.name(), + SurveyInstanceStatus.WITHDRAWN.name()))) .execute(); } diff --git a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyViewDao.java b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyViewDao.java index 1df324c92b..9ab448b0f5 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyViewDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyViewDao.java @@ -30,13 +30,18 @@ import org.finos.waltz.model.survey.SurveyInstanceStatus; import org.finos.waltz.model.survey.SurveyIssuanceKind; import org.finos.waltz.model.survey.SurveyRunStatus; +import org.finos.waltz.schema.tables.SurveyInstance; import org.finos.waltz.schema.tables.records.SurveyInstanceRecord; import org.finos.waltz.schema.tables.records.SurveyRunRecord; +import org.jooq.AggregateFunction; import org.jooq.Condition; import org.jooq.DSLContext; import org.jooq.Field; import org.jooq.Record; +import org.jooq.Record1; +import org.jooq.Select; import org.jooq.SelectConditionStep; +import org.jooq.impl.DSL; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -78,10 +83,13 @@ public class SurveyViewDao { .as("external_id"); private static final String ID_SEPARATOR = ";"; - private static final Condition IS_ORIGINAL_INSTANCE_CONDITION = SURVEY_INSTANCE.ORIGINAL_INSTANCE_ID.isNull(); - private static SurveyInstanceInfo mkSurveyInstanceInfo(Record r, Map> surveyInvolvementGroupKindIds) { + private static final SurveyInstance historicalVersion = SURVEY_INSTANCE.as("historicalVersion"); + + private static SurveyInstanceInfo mkSurveyInstanceInfo(Record r, + Map> surveyInvolvementGroupKindIds, + Map historicalVersions) { SurveyInstanceRecord instanceRecord = r.into(SURVEY_INSTANCE); ImmutableSurveyInstance surveyInstance = ImmutableSurveyInstance.builder() @@ -140,6 +148,8 @@ private static SurveyInstanceInfo mkSurveyInstanceInfo(Record r, Map> surveyInvolvementGroupKindIds = findSurveyInvolvementGroupKindIds(); + Map historicalVersions = getHistoricalVersionCounts(historicalVersion.ORIGINAL_INSTANCE_ID.eq(instanceId)); return dsl .select(SURVEY_INSTANCE.fields()) @@ -181,7 +193,7 @@ public SurveyInstanceInfo getById(long instanceId) { .innerJoin(SURVEY_RUN).on(SURVEY_INSTANCE.SURVEY_RUN_ID.eq(SURVEY_RUN.ID)) .innerJoin(SURVEY_TEMPLATE).on(SURVEY_RUN.SURVEY_TEMPLATE_ID.eq(SURVEY_TEMPLATE.ID)) .where(SURVEY_INSTANCE.ID.eq(instanceId)) - .fetchOne(r -> mkSurveyInstanceInfo(r, surveyInvolvementGroupKindIds)); + .fetchOne(r -> mkSurveyInstanceInfo(r, surveyInvolvementGroupKindIds, historicalVersions)); } @@ -189,6 +201,8 @@ public Set findForRecipient(long personId) { Map> surveyInvolvementGroupKindIds = findSurveyInvolvementGroupKindIds(); + Map historicalVersions = getHistoricalVersionCounts(DSL.trueCondition()); + return dsl .select(SURVEY_INSTANCE.fields()) .select(SURVEY_RUN.fields()) @@ -208,7 +222,7 @@ public Set findForRecipient(long personId) { .and(IS_ORIGINAL_INSTANCE_CONDITION) .and(SURVEY_INSTANCE.STATUS.ne(SurveyInstanceStatus.WITHDRAWN.name())) .and(SURVEY_TEMPLATE.STATUS.eq(ReleaseLifecycleStatus.ACTIVE.name())) - .fetchSet(r -> mkSurveyInstanceInfo(r, surveyInvolvementGroupKindIds)); + .fetchSet(r -> mkSurveyInstanceInfo(r, surveyInvolvementGroupKindIds, historicalVersions)); } @@ -218,6 +232,7 @@ public Set findForOwner(Long personId) { Condition isRunOwnerOrHasOwnerInvolvement = SURVEY_INSTANCE_OWNER.PERSON_ID.eq(personId).or(SURVEY_RUN.OWNER_ID.eq(personId)); Map> surveyInvolvementGroupKindIds = findSurveyInvolvementGroupKindIds(); + Map historicalVersions = getHistoricalVersionCounts(DSL.trueCondition()); SelectConditionStep selectSurveysByOwningInvolvement = dsl .select(SURVEY_INSTANCE.fields()) @@ -259,7 +274,7 @@ public Set findForOwner(Long personId) { return selectSurveysByOwningInvolvement .union(selectSurveysByOwningRole) - .fetchSet(r -> mkSurveyInstanceInfo(r, surveyInvolvementGroupKindIds)); + .fetchSet(r -> mkSurveyInstanceInfo(r, surveyInvolvementGroupKindIds, historicalVersions)); } @@ -281,4 +296,44 @@ private Map> findSurveyInvolvementGroupKindIds() { r -> r.get(INVOLVEMENT_GROUP_ENTRY.INVOLVEMENT_GROUP_ID), r -> r.get(INVOLVEMENT_GROUP_ENTRY.INVOLVEMENT_KIND_ID)); } + + public Set findBySurveyInstanceIdSelector(Select> selector) { + Map> surveyInvolvementGroupKindIds = findSurveyInvolvementGroupKindIds(); + + Map historicalVersions = getHistoricalVersionCounts(historicalVersion.ORIGINAL_INSTANCE_ID.in(selector)); + + SelectConditionStep qry = dsl + .select(SURVEY_INSTANCE.fields()) + .select(SURVEY_RUN.fields()) + .select(SURVEY_TEMPLATE.NAME, + SURVEY_TEMPLATE.ID, + SURVEY_TEMPLATE.DESCRIPTION, + SURVEY_TEMPLATE.EXTERNAL_ID) + .select(ENTITY_NAME_FIELD) + .select(QUALIFIER_NAME_FIELD) + .select(EXTERNAL_ID_FIELD) + .from(SURVEY_INSTANCE) + .innerJoin(SURVEY_RUN).on(SURVEY_INSTANCE.SURVEY_RUN_ID.eq(SURVEY_RUN.ID)) + .innerJoin(SURVEY_TEMPLATE).on(SURVEY_RUN.SURVEY_TEMPLATE_ID.eq(SURVEY_TEMPLATE.ID)) + .where(SURVEY_INSTANCE.ID.in(selector) + .and(IS_ORIGINAL_INSTANCE_CONDITION)); + + return qry + .fetchSet(r -> mkSurveyInstanceInfo(r, surveyInvolvementGroupKindIds, historicalVersions)); + } + + private Map getHistoricalVersionCounts(Condition condition) { + + AggregateFunction surveyCount = DSL.count(); + + return dsl + .select(historicalVersion.ORIGINAL_INSTANCE_ID, surveyCount) + .from(historicalVersion) + .where(historicalVersion.ORIGINAL_INSTANCE_ID.isNotNull()) + .and(condition) + .groupBy(historicalVersion.ORIGINAL_INSTANCE_ID) + .fetchMap( + r -> r.get(historicalVersion.ORIGINAL_INSTANCE_ID), + r -> r.get(surveyCount)); + } } diff --git a/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceInfo.java b/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceInfo.java index 092a38587b..f61869986e 100644 --- a/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceInfo.java +++ b/waltz-model/src/main/java/org/finos/waltz/model/survey/SurveyInstanceInfo.java @@ -32,5 +32,6 @@ public abstract class SurveyInstanceInfo { public abstract SurveyInstance surveyInstance(); public abstract SurveyRun surveyRun(); public abstract EntityReference surveyTemplateRef(); + public abstract Integer historicalVersionsCount(); } diff --git a/waltz-ng/client/survey/components/survey-section.html b/waltz-ng/client/survey/components/survey-section.html index 7e333732cc..7d79984f2b 100644 --- a/waltz-ng/client/survey/components/survey-section.html +++ b/waltz-ng/client/survey/components/survey-section.html @@ -459,8 +459,9 @@

- - + +
diff --git a/waltz-ng/client/survey/components/survey-section.js b/waltz-ng/client/survey/components/survey-section.js index 5f9cd0067e..ad14c554dd 100644 --- a/waltz-ng/client/survey/components/survey-section.js +++ b/waltz-ng/client/survey/components/survey-section.js @@ -24,6 +24,7 @@ import {displayError} from "../../common/error-utils"; import {isSurveyTargetKind} from "../survey-utils"; import toasts from "../../svelte-stores/toast-store"; import SystemRoles from "../../user/system-roles"; +import SurveyInstanceList from "./svelte/SurveyInstanceList.svelte"; const initialState = { @@ -43,7 +44,8 @@ const initialState = { recipientInvolvementKinds: [], ownerInvolvementKinds: [] }, - templateQuery: "" + templateQuery: "", + SurveyInstanceList }; diff --git a/waltz-ng/client/survey/components/svelte/SurveyInstanceList.svelte b/waltz-ng/client/survey/components/svelte/SurveyInstanceList.svelte new file mode 100644 index 0000000000..6040c3f615 --- /dev/null +++ b/waltz-ng/client/survey/components/svelte/SurveyInstanceList.svelte @@ -0,0 +1,293 @@ + + + +
+ Surveys for this entity are listed below in order of issuance date (most recent first). + Use the filters to limit the list or use the search to find instances of a particular template. + Some surveys may have historical versions, click on the survey to see more details. +
+ +
+ + Filters + +
+ +
+
+ Status: +
+ +
+
+ toggleStatus(surveyInstanceStatus.WITHDRAWN.key)}> + {surveyInstanceStatus.WITHDRAWN.name} +
+
+ toggleStatus(surveyInstanceStatus.NOT_STARTED.key)}> + {surveyInstanceStatus.NOT_STARTED.name} +
+
+ toggleStatus(surveyInstanceStatus.IN_PROGRESS.key)}> + {surveyInstanceStatus.IN_PROGRESS.name} +
+
+ toggleStatus(surveyInstanceStatus.COMPLETED.key)}> + {surveyInstanceStatus.COMPLETED.name} +
+
+ toggleStatus(surveyInstanceStatus.APPROVED.key)}> + {surveyInstanceStatus.APPROVED.name} +
+
+ toggleStatus(surveyInstanceStatus.REJECTED.key)}> + {surveyInstanceStatus.REJECTED.name} +
+
+
+ + +
+ +
+ Dates: +
+
+
+ filterIssuedOnDate = !filterIssuedOnDate}/> + {#if filterIssuedOnDate} + setIssuedOnFilterDate(d.detail)}/> + {/if} +
+ +
+ filterSubmissionDate = !filterSubmissionDate}/> + {#if filterSubmissionDate} + setSubmittedFilterDate(d.detail)}/> + {/if} +
+ +
+ filterApprovalDate = !filterApprovalDate}/> + {#if filterApprovalDate} + setApprovedFilterDate(d.detail)}/> + {/if} +
+
+
+ +
+ + + +
+ + +
+
12}> + + + + + + + + + + + + + + + {#each filteredInstances as survey} + goToInstance(survey.surveyInstance.id)} + class="clickable"> + + + + + + + + + + {:else } + + + + {/each} + +
Template NameRun NameInstance NameStatusIssued OnSubmittedApproved + Historical Versions +
{survey.surveyTemplateRef.name}{survey.surveyRun.name || "-"}{survey.surveyInstance.name || "-"}{_.get(surveyInstanceStatus, [survey.surveyInstance.status, "name"], "Unknown")}{survey.surveyInstance.issuedOn} + {#if survey.surveyInstance.submittedAt} + + / {survey.surveyInstance.submittedBy} + {:else} + - + {/if} + + {#if survey.surveyInstance.approvedAt} + + / {survey.surveyInstance.approvedBy} + {:else} + - + {/if} + {survey.historicalVersionsCount}
+ There are no survey results for this entity. There may be filters applied limiting these results. +
+
+ + + \ No newline at end of file diff --git a/waltz-ng/client/svelte-stores/survey-instance-store.js b/waltz-ng/client/svelte-stores/survey-instance-store.js index bd2908188c..e447c19eb9 100644 --- a/waltz-ng/client/svelte-stores/survey-instance-store.js +++ b/waltz-ng/client/svelte-stores/survey-instance-store.js @@ -42,11 +42,14 @@ export function mkSurveyInstanceStore() { const findPreviousVersions = (originalId) => remote .fetchViewList("GET", `api/survey-instance/id/${originalId}/previous-versions`); - const findVersions = (originalId, force = false) => remote .fetchViewList("GET", `api/survey-instance/id/${originalId}/versions`, null, {force}); + const findByRecipientId = (personId, force = false) => remote + .fetchViewList("GET", `api/survey-instance/recipient/id/${personId}`, null, {force}); + const findByEntityReference = (ref, force = false) => remote + .fetchViewList("GET", `api/survey-instance/entity/${ref.kind}/${ref.id}`, null, {force}); const updateStatus = (id, command) => remote .execute("PUT",`api/survey-instance/${id}/status`, command); @@ -111,6 +114,8 @@ export function mkSurveyInstanceStore() { findResponses, findPreviousVersions, findVersions, + findByRecipientId, + findByEntityReference, getPermissions, updateStatus, updateSubmissionDueDate, diff --git a/waltz-ng/client/svelte-stores/survey-instance-view-store.js b/waltz-ng/client/svelte-stores/survey-instance-view-store.js index dce0885136..48d3d83714 100644 --- a/waltz-ng/client/svelte-stores/survey-instance-view-store.js +++ b/waltz-ng/client/svelte-stores/survey-instance-view-store.js @@ -26,6 +26,13 @@ export function mkSurveyInstanceViewStore() { const getFormDetailsById = (id, force = false) => remote .fetchViewDatum("GET", `api/survey-instance-view/form-details/${id}`, null, {force}); + const findByPersonId = (personId, force = false) => remote + .fetchViewList("GET", `api/survey-instance-view/person/id/${personId}`, null, {force}); + + const findByEntityReference = (ref, force = false) => remote + .fetchViewList("GET", `api/survey-instance-view/entity/${ref.kind}/${ref.id}`, null, {force}); + + const findForUser = (force = false) => remote .fetchViewList( "GET", @@ -36,7 +43,9 @@ export function mkSurveyInstanceViewStore() { return { findForUser, getFormDetailsById, - getInfoById + getInfoById, + findByPersonId, + findByEntityReference }; } diff --git a/waltz-ng/client/svelte-stores/survey-run-store.js b/waltz-ng/client/svelte-stores/survey-run-store.js new file mode 100644 index 0000000000..c4f6f72bc8 --- /dev/null +++ b/waltz-ng/client/svelte-stores/survey-run-store.js @@ -0,0 +1,35 @@ +/* + * Waltz - Enterprise Architecture + * Copyright (C) 2016, 2017, 2018, 2019 Waltz open source project + * See README.md for more information + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific + * + */ + +import {remote} from "./remote"; + +export function mkSurveyRunStore() { + + const findByRecipientId = (personId, force = false) => remote + .fetchViewList("GET", `api/survey-run/recipient/id/${personId}`, null, {force}); + + const findByEntityReference = (ref, force = false) => remote + .fetchViewList("GET", `api/survey-run/entity/${ref.kind}/${ref.id}`, null, {force}); + + return { + findByRecipientId, + findByEntityReference + }; +} + +export const surveyRunStore = mkSurveyRunStore(); \ No newline at end of file diff --git a/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceIdSelectorFactory.java b/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceIdSelectorFactory.java index 422ae45c58..cad841e74d 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceIdSelectorFactory.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceIdSelectorFactory.java @@ -49,10 +49,8 @@ public Select> apply(IdSelectionOptions options) { case APPLICATION: case CHANGE_INITIATIVE: return mkForNonHierarchicalEntity(ref, options.scope()); - case ORG_UNIT: return mkForOrgUnit(ref, options.scope()); - default: throw new IllegalArgumentException("Cannot create selector for entity kind: " + ref.kind()); } diff --git a/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceService.java b/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceService.java index 508cb1c9d9..11c67b96b2 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceService.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceService.java @@ -22,7 +22,11 @@ import org.finos.waltz.common.DateTimeUtilities; import org.finos.waltz.common.SetUtilities; import org.finos.waltz.data.person.PersonDao; -import org.finos.waltz.data.survey.*; +import org.finos.waltz.data.survey.SurveyInstanceDao; +import org.finos.waltz.data.survey.SurveyInstanceOwnerDao; +import org.finos.waltz.data.survey.SurveyInstanceRecipientDao; +import org.finos.waltz.data.survey.SurveyQuestionResponseDao; +import org.finos.waltz.data.survey.SurveyRunDao; import org.finos.waltz.model.EntityKind; import org.finos.waltz.model.EntityReference; import org.finos.waltz.model.IdSelectionOptions; @@ -30,7 +34,24 @@ import org.finos.waltz.model.attestation.SyncRecipientsResponse; import org.finos.waltz.model.changelog.ImmutableChangeLog; import org.finos.waltz.model.person.Person; -import org.finos.waltz.model.survey.*; +import org.finos.waltz.model.survey.CopySurveyResponsesCommand; +import org.finos.waltz.model.survey.ImmutableSurveyInstancePermissions; +import org.finos.waltz.model.survey.ImmutableSurveyInstanceQuestionResponse; +import org.finos.waltz.model.survey.ImmutableSurveyInstanceStatusChangeCommand; +import org.finos.waltz.model.survey.SurveyInstance; +import org.finos.waltz.model.survey.SurveyInstanceAction; +import org.finos.waltz.model.survey.SurveyInstanceActionCompletionRequirement; +import org.finos.waltz.model.survey.SurveyInstanceFormDetails; +import org.finos.waltz.model.survey.SurveyInstanceOwnerCreateCommand; +import org.finos.waltz.model.survey.SurveyInstancePermissions; +import org.finos.waltz.model.survey.SurveyInstanceQuestionResponse; +import org.finos.waltz.model.survey.SurveyInstanceRecipientCreateCommand; +import org.finos.waltz.model.survey.SurveyInstanceStateMachine; +import org.finos.waltz.model.survey.SurveyInstanceStatus; +import org.finos.waltz.model.survey.SurveyInstanceStatusChangeCommand; +import org.finos.waltz.model.survey.SurveyQuestion; +import org.finos.waltz.model.survey.SurveyQuestionResponse; +import org.finos.waltz.model.survey.SurveyRun; import org.finos.waltz.model.user.SystemRole; import org.finos.waltz.model.utils.IdUtilities; import org.finos.waltz.service.changelog.ChangeLogService; @@ -41,11 +62,17 @@ import org.springframework.stereotype.Service; import java.time.LocalDate; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import static java.lang.String.format; import static java.util.Collections.emptySet; -import static org.finos.waltz.common.Checks.*; +import static org.finos.waltz.common.Checks.checkNotNull; +import static org.finos.waltz.common.Checks.checkTrue; +import static org.finos.waltz.common.Checks.fail; import static org.finos.waltz.common.CollectionUtilities.find; import static org.finos.waltz.common.CollectionUtilities.isEmpty; import static org.finos.waltz.common.StringUtilities.isEmpty; @@ -233,14 +260,23 @@ public Person checkPersonIsRecipient(String userName, long instanceId) { } - public SurveyInstanceStatus updateStatus(String userName, long instanceId, SurveyInstanceStatusChangeCommand command) { + public SurveyInstanceStatus updateStatus(String userName, + long instanceId, + SurveyInstanceStatusChangeCommand command) { + checkNotNull(command, "command cannot be null"); SurveyInstance surveyInstance = surveyInstanceDao.getById(instanceId); - checkTrue(surveyInstance.originalInstanceId() == null, "You cannot change the status of Approved/Rejected surveys"); + checkTrue(surveyInstance.originalInstanceId() == null, "You can only update the status of the most recent version of a survey"); SurveyInstancePermissions permissions = getPermissions(userName, instanceId); - SurveyInstanceStatus newStatus = simple(surveyInstance.status()).process(command.action(), permissions, surveyInstance); + + //This checks that the command is an allowable transition and that you have the required permissions + SurveyInstanceStatus newStatus = simple(surveyInstance.status()) + .process( + command.action(), + permissions, + surveyInstance); if (command.action().getCompletionRequirement() == SurveyInstanceActionCompletionRequirement.REQUIRE_FULL_COMPLETION) { // abort if missing any mandatory questions @@ -256,26 +292,29 @@ public SurveyInstanceStatus updateStatus(String userName, long instanceId, Surve } int nbupdates = 0; + switch (command.action()) { case APPROVING: + checkTrue(newStatus.equals(SurveyInstanceStatus.APPROVED), "The resolved new status for APPROVING should be 'APPROVED', resolved to: " + newStatus); nbupdates = surveyInstanceDao.markApproved(instanceId, userName); break; + case SUBMITTING: + checkTrue(newStatus.equals(SurveyInstanceStatus.COMPLETED), "The resolved new status for SUBMITTING should be 'COMPLETED', resolved to: " + newStatus); + removeUnnecessaryResponses(instanceId); + nbupdates = surveyInstanceDao.markSubmitted(instanceId, userName); + break; case REOPENING: + checkTrue(newStatus.equals(SurveyInstanceStatus.IN_PROGRESS), "The resolved new status for REOPENING should be 'IN_PROGRESS', resolved to: " + newStatus); // if survey is being sent back, store current responses as a version long versionedInstanceId = surveyInstanceDao.createPreviousVersion(surveyInstance); surveyQuestionResponseDao.cloneResponses(surveyInstance.id().get(), versionedInstanceId); - surveyInstanceDao.clearApproved(instanceId); - // intended drop thru' + nbupdates = surveyInstanceDao.reopenSurvey(instanceId); + break; default: nbupdates = surveyInstanceDao.updateStatus(instanceId, newStatus); } if (nbupdates > 0) { - if (newStatus == SurveyInstanceStatus.COMPLETED) { - surveyInstanceDao.updateSubmitted(instanceId, userName); - removeUnnecessaryResponses(instanceId); - } - changeLogService.write( ImmutableChangeLog.builder() .operation(Operation.UPDATE) diff --git a/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceViewService.java b/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceViewService.java index a8eae696e7..79f955e9e9 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceViewService.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/survey/SurveyInstanceViewService.java @@ -21,8 +21,11 @@ import org.finos.waltz.data.person.PersonDao; import org.finos.waltz.data.survey.SurveyViewDao; +import org.finos.waltz.model.EntityReference; import org.finos.waltz.model.person.Person; import org.finos.waltz.model.survey.*; +import org.jooq.Record1; +import org.jooq.Select; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -30,6 +33,9 @@ import static org.finos.waltz.common.Checks.checkNotNull; import static org.finos.waltz.common.SetUtilities.asSet; +import static org.finos.waltz.common.SetUtilities.union; +import static org.finos.waltz.model.HierarchyQueryScope.EXACT; +import static org.finos.waltz.model.IdSelectionOptions.mkOpts; @Service public class SurveyInstanceViewService { @@ -38,6 +44,8 @@ public class SurveyInstanceViewService { private final SurveyViewDao surveyViewDao; private final SurveyInstanceEvaluator instanceEvaluator; + private final SurveyInstanceIdSelectorFactory surveyInstanceIdSelectorFactory = new SurveyInstanceIdSelectorFactory(); + @Autowired public SurveyInstanceViewService(PersonDao personDao, @@ -59,6 +67,19 @@ public SurveyInstanceInfo getInfoById(long instanceId) { } + public Set findByEntityReference(EntityReference ref) { + Select> selector = surveyInstanceIdSelectorFactory.apply(mkOpts(ref, EXACT)); + return surveyViewDao.findBySurveyInstanceIdSelector(selector); + } + + + public Set findByPersonId(long personId) { + Set surveysOwned = surveyViewDao.findForOwner(personId); + Set surveysAssigned = surveyViewDao.findForRecipient(personId); + return union(surveysOwned, surveysAssigned); + } + + public SurveyInstanceFormDetails getFormDetailsById(long instanceId) { return instanceEvaluator.eval(instanceId); } diff --git a/waltz-web/src/main/java/org/finos/waltz/web/endpoints/api/SurveyInstanceViewEndpoint.java b/waltz-web/src/main/java/org/finos/waltz/web/endpoints/api/SurveyInstanceViewEndpoint.java index accc08ea2e..e7836fc139 100644 --- a/waltz-web/src/main/java/org/finos/waltz/web/endpoints/api/SurveyInstanceViewEndpoint.java +++ b/waltz-web/src/main/java/org/finos/waltz/web/endpoints/api/SurveyInstanceViewEndpoint.java @@ -52,6 +52,8 @@ public SurveyInstanceViewEndpoint(SurveyInstanceViewService surveyInstanceViewSe @Override public void register() { String findForUserPath = mkPath(BASE_URL, "user"); + String findForEntityReferencePath = mkPath(BASE_URL, "entity", ":kind", ":id"); + String findForPersonIdPath = mkPath(BASE_URL, "person", "id", ":id"); String getInfoByIdPath = mkPath(BASE_URL, "id", ":id"); String getFormDetailsByIdPath = mkPath(BASE_URL, "form-details", ":id"); @@ -61,7 +63,15 @@ public void register() { ListRoute findForUserRoute = (req, res) -> surveyInstanceViewService.findForUser(getUsername(req)); + ListRoute findForPersonIdRoute = + (req, res) -> surveyInstanceViewService.findByPersonId(getId(req)); + + ListRoute findForEntityReferenceRoute = + (req, res) -> surveyInstanceViewService.findByEntityReference(getEntityReference(req)); + getForList(findForUserPath, findForUserRoute); + getForList(findForEntityReferencePath, findForEntityReferenceRoute); + getForList(findForPersonIdPath, findForPersonIdRoute); getForDatum(getInfoByIdPath, getInfoByIdRoute); getForDatum(getFormDetailsByIdPath, getFormDetailsByIdRoute); }