@@ -38,6 +38,9 @@ class ProjectService {
38
38
static final String PLAN_SUBMITTED = ' submitted'
39
39
static final String PLAN_UNLOCKED = ' unlocked for correction'
40
40
public static final String DOCUMENT_ROLE_APPROVAL = ' approval'
41
+ public static final String FLATTEN_BY_SUM = " SUM"
42
+ public static final String FLATTEN_BY_COUNT = " COUNT"
43
+ public static final String DEFAULT_GROUP_BY = ' scientificName,vernacularName,scientificNameID,individualsOrGroups'
41
44
42
45
// All projects can use the Plot Selection and Layout, Plot Description and Opportune modules, but
43
46
// we don't want users recording data sets for Plot Selection and Layout so it's not included here.
@@ -2234,12 +2237,12 @@ class ProjectService {
2234
2237
result
2235
2238
}
2236
2239
2237
- List getSpeciesRecordsFromActivity (String activityId ) {
2240
+ List getSpeciesRecordsFromActivity (String activityId , String groupBy = DEFAULT_GROUP_BY , String operator = FLATTEN_BY_SUM ) {
2238
2241
if (activityId) {
2239
2242
String displayFormat = ' SCIENTIFICNAME(COMMONNAME)'
2240
2243
String url = " ${ grailsApplication.config.getProperty('ecodata.baseUrl')} record/listForActivity/${ activityId} "
2241
- def records = webService. getJson(url)?. records
2242
-
2244
+ List records = webService. getJson(url)?. records
2245
+ records = groupRecords(records, groupBy, operator)
2243
2246
records?. each { record ->
2244
2247
record. species = [
2245
2248
scientificName : record. scientificName,
@@ -2254,4 +2257,58 @@ class ProjectService {
2254
2257
records
2255
2258
}
2256
2259
}
2260
+
2261
+ /**
2262
+ * Groups records by the user defined attributes and applies the operator to the numeric values.
2263
+ * @param records - dwc records
2264
+ * @param groupBy - scientificName, individualsOrGroups, etc.
2265
+ * @param operator - SUM
2266
+ * @return
2267
+ */
2268
+ List groupRecords (List records , String groupBy = DEFAULT_GROUP_BY , String operator = FLATTEN_BY_SUM ) {
2269
+ if (records && groupBy) {
2270
+ List groupByAttributes = groupBy. tokenize(' ,' )
2271
+ // Group the records by the user defined attributes such as scientificName, individualsOrGroups, etc.
2272
+ Map recordsByGroup = records. groupBy { dwcRecord ->
2273
+ groupByAttributes. collect { dwcRecord[it] }
2274
+ }
2275
+
2276
+ // For each group, summarize the records by applying the operator
2277
+ Map groupsAndTheirSummary= recordsByGroup. collectEntries { groupKey , groupedRecords ->
2278
+ // iterate over the records in the group and summarize them
2279
+ Map summaryOfGroupedRecords = groupedRecords. inject([:], { newRecord , recordInGroup ->
2280
+ // iterate over the attributes of the record and apply the operator
2281
+ recordInGroup. each { dwcAttribute , dwcValue ->
2282
+ // sum or count all numeric values that are not used for grouping
2283
+ if (dwcAttribute ! in groupByAttributes && dwcValue instanceof Number ) {
2284
+ switch (operator) {
2285
+ case FLATTEN_BY_COUNT :
2286
+ // implement count operator
2287
+ break
2288
+
2289
+ case FLATTEN_BY_SUM :
2290
+ newRecord[dwcAttribute] = (newRecord[dwcAttribute] ?: 0 ) + dwcValue
2291
+ break
2292
+ default :
2293
+ log. error " Unsupported operator: ${ operator} "
2294
+ }
2295
+ }
2296
+ else {
2297
+ // if not a numeric value, just copy the value to the new record
2298
+ newRecord[dwcAttribute] = dwcValue
2299
+ }
2300
+ }
2301
+
2302
+ newRecord
2303
+ })
2304
+
2305
+ // flattens groupedRecords (list) to a map
2306
+ [(groupKey): summaryOfGroupedRecords]
2307
+ }
2308
+
2309
+ return groupsAndTheirSummary. values(). toList()
2310
+ }
2311
+
2312
+ records
2313
+ }
2257
2314
}
0 commit comments