7272import static org .finos .waltz .common .MapUtilities .groupBy ;
7373import static org .finos .waltz .common .MapUtilities .indexBy ;
7474import static org .finos .waltz .common .SetUtilities .*;
75- import static org .finos .waltz .common .StringUtilities .join ;
75+ import static org .finos .waltz .common .StringUtilities .* ;
7676import static org .finos .waltz .common .hierarchy .HierarchyUtilities .toForest ;
7777import static org .finos .waltz .data .JooqUtilities .fieldsWithout ;
7878import static org .finos .waltz .model .EntityReference .mkRef ;
@@ -725,13 +725,13 @@ private Set<ReportGridCell> findCellDataByGridCondition(Condition gridCondition,
725725 gridDefn .fixedColumnDefinitions (),
726726 d -> d .entityFieldReference () == null );
727727
728- Collection <ReportGridFixedColumnDefinition > simpleGridDefs = gridDefinitionsByContainingFieldRef .getOrDefault (true , emptySet ());
729- Collection <ReportGridFixedColumnDefinition > complexGridDefs = gridDefinitionsByContainingFieldRef .getOrDefault (false , emptySet ());
728+ Collection <ReportGridFixedColumnDefinition > simpleColDefs = gridDefinitionsByContainingFieldRef .getOrDefault (true , emptySet ());
729+ Collection <ReportGridFixedColumnDefinition > fieldRefColDefs = gridDefinitionsByContainingFieldRef .getOrDefault (false , emptySet ());
730730
731731 // SIMPLE GRID DEFS
732732
733733 Map <EntityKind , Collection <ReportGridFixedColumnDefinition >> colsByKind = groupBy (
734- simpleGridDefs ,
734+ simpleColDefs ,
735735 ReportGridFixedColumnDefinition ::columnEntityKind );
736736
737737 Map <AdditionalColumnOptions , Collection <ReportGridFixedColumnDefinition >> measurableColumnsByRollupKind = groupBy (
@@ -743,12 +743,12 @@ private Set<ReportGridCell> findCellDataByGridCondition(Condition gridCondition,
743743 d -> d .additionalColumnOptions () == AdditionalColumnOptions .NONE );
744744
745745
746- // COMPLEX GRID DEFS
746+ // FIELD REF COL DEFS
747747
748748 Map <Long , EntityFieldReference > fieldReferencesById = dsl
749749 .select (efr .fields ())
750750 .from (efr )
751- .where (efr .ID .in (map (complexGridDefs , r -> r .entityFieldReference ().id ().get ())))
751+ .where (efr .ID .in (map (fieldRefColDefs , r -> r .entityFieldReference ().id ().get ())))
752752 .fetchMap (
753753 r -> r .get (efr .ID ),
754754 r -> ImmutableEntityFieldReference .builder ()
@@ -759,7 +759,7 @@ private Set<ReportGridCell> findCellDataByGridCondition(Condition gridCondition,
759759 .description (r .get (efr .DESCRIPTION ))
760760 .build ());
761761
762- Map <EntityKind , Set <Tuple2 <ReportGridFixedColumnDefinition , EntityFieldReference >>> complexColsByKind = complexGridDefs
762+ Map <EntityKind , Set <Tuple2 <ReportGridFixedColumnDefinition , EntityFieldReference >>> fieldRefColsByKind = fieldRefColDefs
763763 .stream ()
764764 .map (d -> tuple (d , fieldReferencesById .get (d .entityFieldReference ().id ().get ())))
765765 .collect (groupingBy (t -> t .v2 .entityKind (), toSet ()));
@@ -776,21 +776,139 @@ private Set<ReportGridCell> findCellDataByGridCondition(Condition gridCondition,
776776 measurableColumnsByRollupKind .getOrDefault (AdditionalColumnOptions .PICK_LOWEST , emptySet ())),
777777 fetchExactMeasurableData (genericSelector , measurableColumnsByRollupKind .get (AdditionalColumnOptions .NONE )),
778778 fetchSurveyQuestionResponseData (genericSelector , colsByKind .get (EntityKind .SURVEY_QUESTION )),
779+ fetchSurveyTemplateResponseData (genericSelector , colsByKind .get (EntityKind .SURVEY_TEMPLATE )),
779780 fetchAppGroupData (genericSelector , colsByKind .get (EntityKind .APP_GROUP )),
780- fetchApplicationFieldReferenceData (genericSelector , complexColsByKind .get (EntityKind .APPLICATION )),
781+ fetchApplicationFieldReferenceData (genericSelector , fieldRefColsByKind .get (EntityKind .APPLICATION )),
781782 fetchExactDataTypeData (genericSelector , dataTypeColumnsByIsExact .get (Boolean .TRUE )),
782783 fetchSummaryDataTypeData (genericSelector , dataTypeColumnsByIsExact .get (Boolean .FALSE )),
783- fetchSurveyFieldReferenceData (genericSelector , complexColsByKind .get (EntityKind .SURVEY_INSTANCE )),
784- fetchChangeInitiativeFieldReferenceData (genericSelector , complexColsByKind .get (EntityKind .CHANGE_INITIATIVE )),
784+ fetchSurveyFieldReferenceData (genericSelector , fieldRefColsByKind .get (EntityKind .SURVEY_INSTANCE )),
785+ fetchChangeInitiativeFieldReferenceData (genericSelector , fieldRefColsByKind .get (EntityKind .CHANGE_INITIATIVE )),
785786 fetchAttestationData (genericSelector , colsByKind .get (EntityKind .ATTESTATION )),
786- fetchOrgUnitFieldReferenceData (genericSelector , complexColsByKind .get (EntityKind .ORG_UNIT )),
787+ fetchOrgUnitFieldReferenceData (genericSelector , fieldRefColsByKind .get (EntityKind .ORG_UNIT )),
787788 fetchTagData (genericSelector , colsByKind .get (EntityKind .TAG )),
788789 fetchAliasData (genericSelector , colsByKind .get (EntityKind .ENTITY_ALIAS )),
789790 fetchMeasurableHierarchyData (genericSelector , colsByKind .get (EntityKind .MEASURABLE_CATEGORY )),
790791 fetchEntityStatisticData (genericSelector , colsByKind .get (EntityKind .ENTITY_STATISTIC )));
791792 }
792793 }
793794
795+
796+ private Set <ReportGridCell > fetchSurveyTemplateResponseData (GenericSelector genericSelector ,
797+ Collection <ReportGridFixedColumnDefinition > cols ) {
798+ if (isEmpty (cols )) {
799+ return emptySet ();
800+ } else {
801+ Map <EntityKind , Collection <ReportGridFixedColumnDefinition >> colsByQualifierKind = groupBy (
802+ cols ,
803+ ReportGridFixedColumnDefinition ::columnQualifierKind );
804+
805+ return union (
806+ fetchSurveyRecipients (genericSelector , colsByQualifierKind .getOrDefault (EntityKind .SURVEY_INSTANCE_RECIPIENT , emptySet ())),
807+ fetchSurveyApprovers (genericSelector , colsByQualifierKind .getOrDefault (EntityKind .SURVEY_INSTANCE_OWNER , emptySet ())));
808+ }
809+ }
810+
811+
812+ private Set <ReportGridCell > fetchSurveyApprovers (GenericSelector selector ,
813+ Collection <ReportGridFixedColumnDefinition > cols ) {
814+ return fetchSurveyPeople (
815+ selector ,
816+ cols ,
817+ "Approver" ,
818+ SURVEY_INSTANCE_OWNER ,
819+ SURVEY_INSTANCE_OWNER .SURVEY_INSTANCE_ID ,
820+ SURVEY_INSTANCE_OWNER .PERSON_ID );
821+ }
822+
823+
824+ private Set <ReportGridCell > fetchSurveyRecipients (GenericSelector selector ,
825+ Collection <ReportGridFixedColumnDefinition > cols ) {
826+ return fetchSurveyPeople (
827+ selector ,
828+ cols ,
829+ "Recipient" ,
830+ SURVEY_INSTANCE_RECIPIENT ,
831+ SURVEY_INSTANCE_RECIPIENT .SURVEY_INSTANCE_ID ,
832+ SURVEY_INSTANCE_RECIPIENT .PERSON_ID );
833+ }
834+
835+
836+ private Set <ReportGridCell > fetchSurveyPeople (GenericSelector selector ,
837+ Collection <ReportGridFixedColumnDefinition > cols ,
838+ String htmlColumnHeading ,
839+ Table <?> linkedPersonTable ,
840+ Field <Long > surveyInstanceIdField ,
841+ Field <Long > personIdField ) {
842+
843+ if (isEmpty (cols )) {
844+ return emptySet ();
845+ } else {
846+ Map <Long , Long > templateToColId = indexBy (cols ,
847+ ReportGridFixedColumnDefinition ::columnEntityId ,
848+ ReportGridFixedColumnDefinition ::gridColumnId );
849+
850+ Set <Long > surveyTemplateIds = map (cols , ReportGridFixedColumnDefinition ::columnEntityId );
851+
852+ Field <Long > latestInstance = DSL
853+ .firstValue (SURVEY_INSTANCE .ID )
854+ .over ()
855+ .partitionBy (SURVEY_INSTANCE .ENTITY_ID , SURVEY_INSTANCE .ENTITY_KIND )
856+ .orderBy (SURVEY_INSTANCE .SUBMITTED_AT .desc ().nullsLast ())
857+ .as ("latest_instance" );
858+
859+ Table <Record4 <Long , Long , Long , Long >> surveyInfo = dsl
860+ .select (latestInstance ,
861+ SURVEY_INSTANCE .ID .as ("sid" ),
862+ SURVEY_INSTANCE .ENTITY_ID .as ("eid" ),
863+ SURVEY_RUN .SURVEY_TEMPLATE_ID .as ("tid" ))
864+ .from (SURVEY_INSTANCE )
865+ .innerJoin (SURVEY_RUN )
866+ .on (SURVEY_INSTANCE .SURVEY_RUN_ID .eq (SURVEY_RUN .ID ))
867+ .where (SURVEY_INSTANCE .ENTITY_ID .in (selector .selector ())
868+ .and (SURVEY_INSTANCE .ENTITY_KIND .eq (selector .kind ().name ()))
869+ .and (SURVEY_RUN .SURVEY_TEMPLATE_ID .in (surveyTemplateIds ))
870+ .and (SURVEY_INSTANCE .ORIGINAL_INSTANCE_ID .isNull ()))
871+ .asTable ();
872+
873+ SelectConditionStep <Record > qry = dsl
874+ .select (surveyInfo .fields ())
875+ .select (PERSON .EMAIL , PERSON .DISPLAY_NAME , PERSON .EMPLOYEE_ID )
876+ .from (surveyInfo )
877+ .innerJoin (linkedPersonTable ).on (surveyInstanceIdField .eq (latestInstance ))
878+ .innerJoin (PERSON ).on (PERSON .ID .eq (personIdField ).and (PERSON .IS_REMOVED .isFalse ()))
879+ .where (surveyInfo .field (latestInstance )
880+ .eq (surveyInfo .field ("sid" , Long .class )));
881+
882+ return qry
883+ .fetchGroups (
884+ r -> tuple (
885+ r .get ("eid" , Long .class ),
886+ r .get ("tid" , Long .class )),
887+ r -> tuple (
888+ r .get (PERSON .DISPLAY_NAME ),
889+ r .get (PERSON .EMAIL ),
890+ r .get (PERSON .EMPLOYEE_ID )))
891+ .entrySet ()
892+ .stream ()
893+ .map (kv -> kv .getKey ().concat (kv .getValue ()))
894+ .map (t -> t .map2 (templateToColId ::get )) // templateId
895+ .map (t -> ImmutableReportGridCell
896+ .builder ()
897+ .textValue (t .v3 // people
898+ .stream ()
899+ .map (p -> toMailbox (p .v1 , p .v2 )) // display name, email
900+ .collect (joining ("; " )))
901+ .comment (toHtmlTable (
902+ asList (htmlColumnHeading , "email" , "Employee id" ),
903+ t .v3 ))
904+ .columnDefinitionId (t .v2 ) // colId
905+ .subjectId (t .v1 ) // entityId
906+ .build ())
907+ .collect (toSet ());
908+ }
909+ }
910+
911+
794912 public Set <ReportGridCell > fetchMeasurableHierarchyData (GenericSelector genericSelector ,
795913 Collection <ReportGridFixedColumnDefinition > cols ) {
796914 if (isEmpty (cols )) {
@@ -1504,33 +1622,42 @@ private Set<ReportGridCell> fetchInvolvementData(GenericSelector selector,
15041622 ReportGridFixedColumnDefinition ::columnEntityId ,
15051623 ReportGridFixedColumnDefinition ::gridColumnId );
15061624
1507- return fromCollection ( dsl
1625+ return dsl
15081626 .select (
15091627 inv .ENTITY_ID ,
15101628 inv .KIND_ID ,
1511- p .EMAIL )
1629+ p .EMAIL ,
1630+ p .DISPLAY_NAME ,
1631+ p .EMPLOYEE_ID )
15121632 .from (inv )
15131633 .innerJoin (p ).on (p .EMPLOYEE_ID .eq (inv .EMPLOYEE_ID ))
15141634 .where (inv .ENTITY_KIND .eq (selector .kind ().name ()))
15151635 .and (inv .ENTITY_ID .in (selector .selector ()))
15161636 .and (inv .KIND_ID .in (involvementIdToDefIdMap .keySet ()))
15171637 .and (p .IS_REMOVED .isFalse ())
1518- .fetchSet (r -> ImmutableReportGridCell
1638+ .fetchGroups (
1639+ r -> tuple (
1640+ r .get (inv .ENTITY_ID ),
1641+ involvementIdToDefIdMap .get (r .get (inv .KIND_ID ))),
1642+ r -> tuple (
1643+ r .get (p .DISPLAY_NAME ),
1644+ r .get (p .EMAIL ),
1645+ r .get (p .EMPLOYEE_ID ))) // {(subject, colDefId) -> (display, email, empId)}
1646+ .entrySet ()
1647+ .stream ()
1648+ .map (kv -> ImmutableReportGridCell
15191649 .builder ()
1520- .subjectId (r .get (inv .ENTITY_ID ))
1521- .columnDefinitionId (involvementIdToDefIdMap .get (r .get (inv .KIND_ID )))
1522- .textValue (r .get (p .EMAIL ))
1650+ .textValue (kv .getValue () // people
1651+ .stream ()
1652+ .map (p -> toMailbox (p .v1 , p .v2 )) // display name, email
1653+ .collect (joining ("; " )))
1654+ .comment (toHtmlTable (
1655+ asList ("Person" , "email" , "Employee id" ),
1656+ kv .getValue ()))
1657+ .subjectId (kv .getKey ().v1 ) // entityId
1658+ .columnDefinitionId (kv .getKey ().v2 ) // colId
15231659 .build ())
1524- // we now convert to a map so we can merge text values of cells with the same coordinates (appId, entId)
1525- .stream ()
1526- .collect (toMap (
1527- c -> tuple (c .subjectId (), c .columnDefinitionId ()),
1528- identity (),
1529- (a , b ) -> ImmutableReportGridCell
1530- .copyOf (a )
1531- .withTextValue (a .textValue () + "; " + b .textValue ())))
1532- // and then we simply return the values of that temporary map.
1533- .values ());
1660+ .collect (Collectors .toSet ());
15341661 }
15351662 }
15361663
0 commit comments