From 1223f0413f2f9d4a9dc2b7f6382536c80fcf160c Mon Sep 17 00:00:00 2001 From: woodjes Date: Thu, 10 Mar 2022 09:33:31 +0000 Subject: [PATCH 1/7] Report grids can display group involvement #CTCOWALTZ-2451 #5962 --- .../waltz/data/report_grid/ReportGridDao.java | 82 ++++++++++++++++++- .../report-grid-view-section.html | 6 ++ .../components/svelte/report-grid-utils.js | 3 + 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java index 979e567b00..9fdddbc194 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java @@ -39,6 +39,7 @@ import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Repository; +import java.sql.Timestamp; import java.util.Comparator; import java.util.*; import java.util.function.Function; @@ -50,11 +51,11 @@ import static java.util.Collections.emptySet; import static java.util.function.Function.identity; import static java.util.stream.Collectors.*; +import static org.finos.waltz.common.DateTimeUtilities.toLocalDate; import static org.finos.waltz.common.DateTimeUtilities.toLocalDateTime; import static org.finos.waltz.common.ListUtilities.newArrayList; import static org.finos.waltz.common.MapUtilities.groupBy; -import static org.finos.waltz.common.SetUtilities.map; -import static org.finos.waltz.common.SetUtilities.union; +import static org.finos.waltz.common.SetUtilities.*; import static org.finos.waltz.common.StringUtilities.join; import static org.finos.waltz.model.EntityReference.mkRef; import static org.finos.waltz.model.survey.SurveyInstanceStatus.APPROVED; @@ -83,6 +84,9 @@ public class ReportGridDao { private final org.finos.waltz.schema.tables.InvolvementKind ik = INVOLVEMENT_KIND.as("ik"); private final org.finos.waltz.schema.tables.Person p = Tables.PERSON.as("p"); private final org.finos.waltz.schema.tables.SurveyQuestion sq = SURVEY_QUESTION.as("sq"); + private final org.finos.waltz.schema.tables.ApplicationGroup ag = APPLICATION_GROUP.as("ag"); + private final org.finos.waltz.schema.tables.ApplicationGroupEntry age = APPLICATION_GROUP_ENTRY.as("age"); + private final org.finos.waltz.schema.tables.ApplicationGroupOuEntry agoe = APPLICATION_GROUP_OU_ENTRY.as("agoe"); private final org.finos.waltz.schema.tables.EntityFieldReference efr = ENTITY_FIELD_REFERENCE.as("efr"); private final org.finos.waltz.schema.tables.SurveyTemplate st = SURVEY_TEMPLATE.as("st"); private final org.finos.waltz.schema.tables.Application a = APPLICATION.as("a"); @@ -258,6 +262,14 @@ private List getColumnDefinitions(Condition conditio sq.HELP_TEXT, condition); + SelectConditionStep> appGroupColumns = mkColumnDefinitionQuery( + EntityKind.APP_GROUP, + ag, + ag.ID, + ag.NAME, + ag.DESCRIPTION, + condition); + SelectConditionStep> surveyMetaColumns = mkColumnDefinitionQuery( EntityKind.SURVEY_TEMPLATE, st, @@ -287,6 +299,7 @@ private List getColumnDefinitions(Condition conditio .unionAll(costKindColumns) .unionAll(involvementKindColumns) .unionAll(surveyQuestionColumns) + .unionAll(appGroupColumns) .unionAll(surveyMetaColumns) .unionAll(applicationMetaColumns) .unionAll(changeInitiativeMetaColumns) @@ -405,6 +418,10 @@ private Set findCellDataByGridCondition(Condition gridCondition, colsByKind.getOrDefault(EntityKind.SURVEY_QUESTION, emptySet()), cd -> cd.columnEntityId()); + Set requiredAppGroupIds = map( + colsByKind.getOrDefault(EntityKind.APP_GROUP, emptySet()), + cd -> cd.columnEntityId()); + // COMPLEX GRID DEFS @@ -443,6 +460,7 @@ private Set findCellDataByGridCondition(Condition gridCondition, fetchCostData(genericSelector, requiredCostKinds), fetchInvolvementData(genericSelector, requiredInvolvementKinds), fetchSurveyQuestionResponseData(genericSelector, requiredSurveyQuestionIds), + fetchAppGroupData(genericSelector, requiredAppGroupIds), fetchSurveyFieldReferenceData(genericSelector, requiredSurveyTemplateIds), fetchApplicationFieldReferenceData(genericSelector, requiredApplicationColumns), fetchChangeInitiativeFieldReferenceData(genericSelector, requiredChangeInitiativeColumns)); @@ -450,6 +468,64 @@ private Set findCellDataByGridCondition(Condition gridCondition, } + private Set fetchAppGroupData(GenericSelector genericSelector, + Set requiredAppGroupIds) { + if (requiredAppGroupIds.size() == 0) { + return emptySet(); + } else { + + SelectConditionStep> directSelect = dsl + .select( + age.APPLICATION_ID.as("application_id"), + ag.ID, + age.CREATED_AT.as("created_at")) + .from(ag) + .innerJoin(age).on(ag.ID.eq(age.GROUP_ID)) + .where(age.APPLICATION_ID.in(genericSelector.selector())) + .and(ag.ID.in(requiredAppGroupIds)); + + SelectConditionStep> indirectSelect = dsl + .select( + a.ID.as("application_id"), + ag.ID, + agoe.CREATED_AT.as("created_at")) + .from(ag) + .innerJoin(agoe).on(ag.ID.eq(agoe.GROUP_ID)) + .innerJoin(eh).on(agoe.GROUP_ID.eq(eh.ANCESTOR_ID) + .and(eh.KIND.eq(EntityKind.ORG_UNIT.name()))) + .innerJoin(a).on(eh.ID.eq(a.ORGANISATIONAL_UNIT_ID)) + .where(a.ID.in(genericSelector.selector())) + .and(ag.ID.in(requiredAppGroupIds)); + + return fromCollection(directSelect.union(indirectSelect) + .fetchSet(r -> { + Long application_id = r.get("application_id", Long.class); + Timestamp created_at = r.get("created_at", Timestamp.class); + + return ImmutableReportGridCell + .builder() + .subjectId(application_id) + .columnEntityId(r.get(ag.ID)) + .columnEntityKind(EntityKind.APP_GROUP) + .text("Y") + .comment(toLocalDate(created_at).toString()) + .entityFieldReferenceId(null) + .build(); + }) + // we now convert to a map so we can merge text values of cells with the same coordinates (appId, entId) + .stream() + .collect(toMap( + c -> tuple(c.subjectId(), c.columnEntityId()), + identity(), + (a, b) -> ImmutableReportGridCell + .copyOf(a) + .withText(a.text() + "; " + b.text()))) + // and then we simply return the values of that temporary map. + .values()); + } + } + + public Set fetchApplicationFieldReferenceData(GenericSelector selector, Set> requiredApplicationColumns) { @@ -625,7 +701,7 @@ private Set fetchInvolvementData(GenericSelector selector, if (requiredInvolvementKinds.size() == 0) { return emptySet(); } else { - return SetUtilities.fromCollection(dsl + return fromCollection(dsl .select( inv.ENTITY_ID, inv.KIND_ID, diff --git a/waltz-ng/client/report-grid/components/grid-view-section/report-grid-view-section.html b/waltz-ng/client/report-grid/components/grid-view-section/report-grid-view-section.html index f7d25e2274..170006fd12 100644 --- a/waltz-ng/client/report-grid/components/grid-view-section/report-grid-view-section.html +++ b/waltz-ng/client/report-grid/components/grid-view-section/report-grid-view-section.html @@ -2,9 +2,15 @@ .wgrc-involvement-cell { background-color: #e0ffe1; } + .wgrc-survey-question-cell { background-color: #fff59d; } + + .wgrc-app-group-cell { + background-color: #d1dbff; + } + .wgrc-no-data-cell { background-color: #f7f9f9; } diff --git a/waltz-ng/client/report-grid/components/svelte/report-grid-utils.js b/waltz-ng/client/report-grid/components/svelte/report-grid-utils.js index 31c9933c0e..bd90a30c8a 100644 --- a/waltz-ng/client/report-grid/components/svelte/report-grid-utils.js +++ b/waltz-ng/client/report-grid/components/svelte/report-grid-utils.js @@ -172,6 +172,7 @@ export function prepareColumnDefs(gridData) { case "SURVEY_TEMPLATE": case "APPLICATION": case "CHANGE_INITIATIVE": + case "APP_GROUP": case "SURVEY_QUESTION": return { allowSummary: false, @@ -187,6 +188,7 @@ export function prepareColumnDefs(gridData) { popover-placement="left" ng-class="{'wgrc-involvement-cell': COL_FIELD.text && ${c.columnEntityKind === "INVOLVEMENT_KIND"}, 'wgrc-survey-question-cell': COL_FIELD.text && ${c.columnEntityKind === "SURVEY_QUESTION"}, + 'wgrc-app-group-cell': COL_FIELD.text && ${c.columnEntityKind === "APP_GROUP"}, 'wgrc-no-data-cell': !COL_FIELD.text}" ng-style="{ 'border-bottom-right-radius': COL_FIELD.comment ? '15% 50%' : 0, @@ -294,6 +296,7 @@ export function prepareTableData(gridData) { case "SURVEY_TEMPLATE": case "APPLICATION": case "CHANGE_INITIATIVE": + case "APP_GROUP": case "SURVEY_QUESTION": return { text: x.text, From c29f8f339f4567105e18a451bc9da8ca8c18fa80 Mon Sep 17 00:00:00 2001 From: woodjes Date: Thu, 10 Mar 2022 13:11:04 +0000 Subject: [PATCH 2/7] Allow addition of app group columns to grid #CTCOWALTZ-2451 #5962 --- .../ColumnDefinitionEditPanel.svelte | 5 ++ .../EntitySelector.svelte | 1 + .../svelte/pickers/AppGroupPicker.svelte | 56 +++++++++++++++++++ .../svelte/pickers/EntityPicker.svelte | 3 + 4 files changed, 65 insertions(+) create mode 100644 waltz-ng/client/report-grid/components/svelte/pickers/AppGroupPicker.svelte diff --git a/waltz-ng/client/report-grid/components/svelte/column-definition-edit-panel/ColumnDefinitionEditPanel.svelte b/waltz-ng/client/report-grid/components/svelte/column-definition-edit-panel/ColumnDefinitionEditPanel.svelte index 5b6ffd471e..740a019197 100644 --- a/waltz-ng/client/report-grid/components/svelte/column-definition-edit-panel/ColumnDefinitionEditPanel.svelte +++ b/waltz-ng/client/report-grid/components/svelte/column-definition-edit-panel/ColumnDefinitionEditPanel.svelte @@ -27,6 +27,7 @@ let canBeAdded; function onSelect(d) { + const column = { columnEntityId: d.columnEntityId, columnEntityKind: d.columnEntityKind, @@ -39,6 +40,10 @@ position: 0 }; + if (_.some($columnDefs, c => sameColumnRef(column, c))) { + return; + } + const newList = _.concat( $columnDefs, column); diff --git a/waltz-ng/client/report-grid/components/svelte/column-definition-edit-panel/EntitySelector.svelte b/waltz-ng/client/report-grid/components/svelte/column-definition-edit-panel/EntitySelector.svelte index 6e70828451..6935890597 100644 --- a/waltz-ng/client/report-grid/components/svelte/column-definition-edit-panel/EntitySelector.svelte +++ b/waltz-ng/client/report-grid/components/svelte/column-definition-edit-panel/EntitySelector.svelte @@ -19,6 +19,7 @@ entity.SURVEY_QUESTION, entity.ASSESSMENT_DEFINITION, entity.MEASURABLE, + entity.APP_GROUP, entity.SURVEY_INSTANCE, entity.APPLICATION, entity.CHANGE_INITIATIVE diff --git a/waltz-ng/client/report-grid/components/svelte/pickers/AppGroupPicker.svelte b/waltz-ng/client/report-grid/components/svelte/pickers/AppGroupPicker.svelte new file mode 100644 index 0000000000..da8f937426 --- /dev/null +++ b/waltz-ng/client/report-grid/components/svelte/pickers/AppGroupPicker.svelte @@ -0,0 +1,56 @@ + + +
+ + Select an app group using the search below. +
+
+ + \ No newline at end of file diff --git a/waltz-ng/client/report-grid/components/svelte/pickers/EntityPicker.svelte b/waltz-ng/client/report-grid/components/svelte/pickers/EntityPicker.svelte index 80eb1cf6ab..2a5bd87ff2 100644 --- a/waltz-ng/client/report-grid/components/svelte/pickers/EntityPicker.svelte +++ b/waltz-ng/client/report-grid/components/svelte/pickers/EntityPicker.svelte @@ -8,6 +8,7 @@ import SurveyInstanceFieldPicker from "./SurveyInstanceFieldPicker.svelte"; import ApplicationFieldPicker from "./ApplicationFieldPicker.svelte"; import ChangeInitiativeFieldPicker from "./ChangeInitiativeFieldPicker.svelte"; + import AppGroupPicker from "./AppGroupPicker.svelte"; export let onSelect = (d) => console.log("Selecting an entity", d); export let onDeselect = (d) => console.log("Deselecting an entity", d); @@ -32,6 +33,8 @@ return ApplicationFieldPicker; case "CHANGE_INITIATIVE": return ChangeInitiativeFieldPicker; + case "APP_GROUP": + return AppGroupPicker; default: throw "Cannot find picker for kind: " + entityKind; } From fde52ccc547bed3e86134d06eeaeb743bdb9a555 Mon Sep 17 00:00:00 2001 From: woodjes Date: Thu, 10 Mar 2022 13:36:54 +0000 Subject: [PATCH 3/7] Org unit select #CTCOWALTZ-2451 #5962 --- .../java/org/finos/waltz/data/report_grid/ReportGridDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java index 9fdddbc194..b3eaa71e2a 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java @@ -491,7 +491,7 @@ private Set fetchAppGroupData(GenericSelector genericSelector, agoe.CREATED_AT.as("created_at")) .from(ag) .innerJoin(agoe).on(ag.ID.eq(agoe.GROUP_ID)) - .innerJoin(eh).on(agoe.GROUP_ID.eq(eh.ANCESTOR_ID) + .innerJoin(eh).on(agoe.ORG_UNIT_ID.eq(eh.ANCESTOR_ID) .and(eh.KIND.eq(EntityKind.ORG_UNIT.name()))) .innerJoin(a).on(eh.ID.eq(a.ORGANISATIONAL_UNIT_ID)) .where(a.ID.in(genericSelector.selector())) From cb3dcadeb733098de7de2d7c85e1c16f23b8d6d8 Mon Sep 17 00:00:00 2001 From: woodjes Date: Thu, 10 Mar 2022 13:49:25 +0000 Subject: [PATCH 4/7] Extractor supports app group columns #CTCOWALTZ-2451 #5962 --- .../finos/waltz/web/endpoints/extracts/ReportGridExtractor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/ReportGridExtractor.java b/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/ReportGridExtractor.java index bf491a4a1d..cc0ed8f4c4 100644 --- a/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/ReportGridExtractor.java +++ b/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/ReportGridExtractor.java @@ -287,6 +287,7 @@ private Object getValueFromReportCell(Map ratingsById, case APPLICATION: case CHANGE_INITIATIVE: case SURVEY_QUESTION: + case APP_GROUP: return Optional.ofNullable(reportGridCell.text()).orElse("-"); case MEASURABLE: case ASSESSMENT_DEFINITION: From 6ff8d1531a7a90151a857d6eb8d78df45114bfc4 Mon Sep 17 00:00:00 2001 From: woodjes Date: Fri, 11 Mar 2022 11:01:46 +0000 Subject: [PATCH 5/7] App group columns for CIs #CTCOWALTZ-2451 #5962 --- .../waltz/data/report_grid/ReportGridDao.java | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java index b3eaa71e2a..ae2578b16b 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java @@ -20,7 +20,6 @@ import org.finos.waltz.common.DateTimeUtilities; -import org.finos.waltz.common.SetUtilities; import org.finos.waltz.data.GenericSelector; import org.finos.waltz.data.InlineSelectFieldFactory; import org.finos.waltz.model.EntityKind; @@ -91,6 +90,7 @@ public class ReportGridDao { private final org.finos.waltz.schema.tables.SurveyTemplate st = SURVEY_TEMPLATE.as("st"); private final org.finos.waltz.schema.tables.Application a = APPLICATION.as("a"); private final org.finos.waltz.schema.tables.ChangeInitiative ci = CHANGE_INITIATIVE.as("ci"); + private final org.finos.waltz.schema.tables.EntityRelationship er = ENTITY_RELATIONSHIP.as("er"); private static final Field ENTITY_NAME_FIELD = InlineSelectFieldFactory.mkNameField( SURVEY_QUESTION_RESPONSE.ENTITY_RESPONSE_ID, @@ -476,7 +476,7 @@ private Set fetchAppGroupData(GenericSelector genericSelector, SelectConditionStep> directSelect = dsl .select( - age.APPLICATION_ID.as("application_id"), + age.APPLICATION_ID.as("subject_id"), ag.ID, age.CREATED_AT.as("created_at")) .from(ag) @@ -486,7 +486,7 @@ private Set fetchAppGroupData(GenericSelector genericSelector, SelectConditionStep> indirectSelect = dsl .select( - a.ID.as("application_id"), + a.ID.as("subject_id"), ag.ID, agoe.CREATED_AT.as("created_at")) .from(ag) @@ -497,18 +497,46 @@ private Set fetchAppGroupData(GenericSelector genericSelector, .where(a.ID.in(genericSelector.selector())) .and(ag.ID.in(requiredAppGroupIds)); - return fromCollection(directSelect.union(indirectSelect) + SelectConditionStep> groupASelect = dsl + .select(ci.ID.as("subject_id"), + ag.ID, + er.LAST_UPDATED_AT.as("created_at")) + .from(ag) + .innerJoin(er).on(ag.ID.eq(er.ID_A)) + .innerJoin(ci).on(er.ID_B.eq(ci.ID)) + .where(er.KIND_A.eq(EntityKind.APP_GROUP.name()) + .and(er.KIND_B.eq(EntityKind.CHANGE_INITIATIVE.name()))) + .and(ci.ID.in(genericSelector.selector())) + .and(ag.ID.in(requiredAppGroupIds)); + + SelectConditionStep> groupBSelect = dsl + .select(ci.ID.as("subject_id"), + ag.ID, + er.LAST_UPDATED_AT.as("created_at")) + .from(ag) + .innerJoin(er).on(ag.ID.eq(er.ID_B)) + .innerJoin(ci).on(er.ID_A.eq(ci.ID)) + .where(er.KIND_B.eq(EntityKind.APP_GROUP.name()) + .and(er.KIND_A.eq(EntityKind.CHANGE_INITIATIVE.name()))) + .and(ci.ID.in(genericSelector.selector())) + .and(ag.ID.in(requiredAppGroupIds)); + + SelectOrderByStep> groupMembershipSelect = genericSelector.kind().equals(EntityKind.APPLICATION) + ? directSelect.union(indirectSelect) + : groupASelect.union(groupBSelect); + + return fromCollection(groupMembershipSelect .fetchSet(r -> { - Long application_id = r.get("application_id", Long.class); + Long subjectId = r.get("subject_id", Long.class); Timestamp created_at = r.get("created_at", Timestamp.class); return ImmutableReportGridCell .builder() - .subjectId(application_id) + .subjectId(subjectId) .columnEntityId(r.get(ag.ID)) .columnEntityKind(EntityKind.APP_GROUP) .text("Y") - .comment(toLocalDate(created_at).toString()) + .comment(format("Created at: %s", toLocalDate(created_at).toString())) .entityFieldReferenceId(null) .build(); }) From e9f24ad3e06a644e214ef7c07453080339bd6a90 Mon Sep 17 00:00:00 2001 From: woodjes Date: Thu, 17 Mar 2022 11:12:37 +0000 Subject: [PATCH 6/7] Pull out method for determining query #CTCOWALTZ-2451 #5962 --- .../waltz/data/report_grid/ReportGridDao.java | 143 ++++++++++-------- 1 file changed, 81 insertions(+), 62 deletions(-) diff --git a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java index ae2578b16b..e4d778d660 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java @@ -474,59 +474,12 @@ private Set fetchAppGroupData(GenericSelector genericSelector, return emptySet(); } else { - SelectConditionStep> directSelect = dsl - .select( - age.APPLICATION_ID.as("subject_id"), - ag.ID, - age.CREATED_AT.as("created_at")) - .from(ag) - .innerJoin(age).on(ag.ID.eq(age.GROUP_ID)) - .where(age.APPLICATION_ID.in(genericSelector.selector())) - .and(ag.ID.in(requiredAppGroupIds)); - - SelectConditionStep> indirectSelect = dsl - .select( - a.ID.as("subject_id"), - ag.ID, - agoe.CREATED_AT.as("created_at")) - .from(ag) - .innerJoin(agoe).on(ag.ID.eq(agoe.GROUP_ID)) - .innerJoin(eh).on(agoe.ORG_UNIT_ID.eq(eh.ANCESTOR_ID) - .and(eh.KIND.eq(EntityKind.ORG_UNIT.name()))) - .innerJoin(a).on(eh.ID.eq(a.ORGANISATIONAL_UNIT_ID)) - .where(a.ID.in(genericSelector.selector())) - .and(ag.ID.in(requiredAppGroupIds)); - - SelectConditionStep> groupASelect = dsl - .select(ci.ID.as("subject_id"), - ag.ID, - er.LAST_UPDATED_AT.as("created_at")) - .from(ag) - .innerJoin(er).on(ag.ID.eq(er.ID_A)) - .innerJoin(ci).on(er.ID_B.eq(ci.ID)) - .where(er.KIND_A.eq(EntityKind.APP_GROUP.name()) - .and(er.KIND_B.eq(EntityKind.CHANGE_INITIATIVE.name()))) - .and(ci.ID.in(genericSelector.selector())) - .and(ag.ID.in(requiredAppGroupIds)); - - SelectConditionStep> groupBSelect = dsl - .select(ci.ID.as("subject_id"), - ag.ID, - er.LAST_UPDATED_AT.as("created_at")) - .from(ag) - .innerJoin(er).on(ag.ID.eq(er.ID_B)) - .innerJoin(ci).on(er.ID_A.eq(ci.ID)) - .where(er.KIND_B.eq(EntityKind.APP_GROUP.name()) - .and(er.KIND_A.eq(EntityKind.CHANGE_INITIATIVE.name()))) - .and(ci.ID.in(genericSelector.selector())) - .and(ag.ID.in(requiredAppGroupIds)); - - SelectOrderByStep> groupMembershipSelect = genericSelector.kind().equals(EntityKind.APPLICATION) - ? directSelect.union(indirectSelect) - : groupASelect.union(groupBSelect); - - return fromCollection(groupMembershipSelect - .fetchSet(r -> { + SelectOrderByStep> appGroupInfoSelect = determineAppGroupQuery(genericSelector, requiredAppGroupIds); + + return dsl + .fetch(appGroupInfoSelect) + .stream() + .map(r -> { Long subjectId = r.get("subject_id", Long.class); Timestamp created_at = r.get("created_at", Timestamp.class); @@ -541,19 +494,85 @@ private Set fetchAppGroupData(GenericSelector genericSelector, .build(); }) // we now convert to a map so we can merge text values of cells with the same coordinates (appId, entId) - .stream() - .collect(toMap( - c -> tuple(c.subjectId(), c.columnEntityId()), - identity(), - (a, b) -> ImmutableReportGridCell - .copyOf(a) - .withText(a.text() + "; " + b.text()))) - // and then we simply return the values of that temporary map. - .values()); + .collect(toSet()); } } + private SelectOrderByStep> determineAppGroupQuery(GenericSelector selector, Set requiredAppGroupIds) { + + switch (selector.kind()) { + case APPLICATION: + return mkApplicationAppGroupSelect(selector, requiredAppGroupIds); + case CHANGE_INITIATIVE: + return mkChangeInitiativeAppGroupSelect(selector, requiredAppGroupIds); + default: + throw new UnsupportedOperationException("Cannot return app group selector for kind: " + selector.kind().name()); + } + + } + + + private SelectOrderByStep> mkChangeInitiativeAppGroupSelect(GenericSelector selector, Set requiredAppGroupIds) { + + SelectConditionStep> groupASelect = dsl + .select(ci.ID.as("subject_id"), + ag.ID, + er.LAST_UPDATED_AT.as("created_at")) + .from(ag) + .innerJoin(er).on(ag.ID.eq(er.ID_A)) + .innerJoin(ci).on(er.ID_B.eq(ci.ID)) + .where(er.KIND_A.eq(EntityKind.APP_GROUP.name()) + .and(er.KIND_B.eq(EntityKind.CHANGE_INITIATIVE.name()))) + .and(ci.ID.in(selector.selector())) + .and(ag.ID.in(requiredAppGroupIds)); + + SelectConditionStep> groupBSelect = dsl + .select(ci.ID.as("subject_id"), + ag.ID, + er.LAST_UPDATED_AT.as("created_at")) + .from(ag) + .innerJoin(er).on(ag.ID.eq(er.ID_B)) + .innerJoin(ci).on(er.ID_A.eq(ci.ID)) + .where(er.KIND_B.eq(EntityKind.APP_GROUP.name()) + .and(er.KIND_A.eq(EntityKind.CHANGE_INITIATIVE.name()))) + .and(ci.ID.in(selector.selector())) + .and(ag.ID.in(requiredAppGroupIds)); + + + return groupASelect.union(groupBSelect); + } + + + private SelectOrderByStep> mkApplicationAppGroupSelect(GenericSelector selector, Set requiredAppGroupIds) { + + SelectConditionStep> directSelect = DSL + .select( + age.APPLICATION_ID.as("subject_id"), + ag.ID, + age.CREATED_AT.as("created_at")) + .from(ag) + .innerJoin(age).on(ag.ID.eq(age.GROUP_ID)) + .where(age.APPLICATION_ID.in(selector.selector())) + .and(ag.ID.in(requiredAppGroupIds)); + + SelectConditionStep> indirectSelect = DSL + .select( + a.ID.as("subject_id"), + ag.ID, + agoe.CREATED_AT.as("created_at")) + .from(ag) + .innerJoin(agoe).on(ag.ID.eq(agoe.GROUP_ID)) + .innerJoin(eh).on(agoe.ORG_UNIT_ID.eq(eh.ANCESTOR_ID) + .and(eh.KIND.eq(EntityKind.ORG_UNIT.name()))) + .innerJoin(a).on(eh.ID.eq(a.ORGANISATIONAL_UNIT_ID)) + .where(a.ID.in(selector.selector())) + .and(ag.ID.in(requiredAppGroupIds)); + + return directSelect.union(indirectSelect); + } + + public Set fetchApplicationFieldReferenceData(GenericSelector selector, Set> requiredApplicationColumns) { From 3d3abdf08dabaf9de4e0f2fa2a75b1144564e75f Mon Sep 17 00:00:00 2001 From: woodjes Date: Thu, 17 Mar 2022 11:17:29 +0000 Subject: [PATCH 7/7] Removing comment #CTCOWALTZ-2451 #5962 --- .../java/org/finos/waltz/data/report_grid/ReportGridDao.java | 1 - 1 file changed, 1 deletion(-) diff --git a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java index e4d778d660..0404c2a520 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/report_grid/ReportGridDao.java @@ -493,7 +493,6 @@ private Set fetchAppGroupData(GenericSelector genericSelector, .entityFieldReferenceId(null) .build(); }) - // we now convert to a map so we can merge text values of cells with the same coordinates (appId, entId) .collect(toSet()); } }