Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into feature/paratoo
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisala committed Nov 27, 2023
2 parents e255e81 + 88ba8f0 commit 24e62dc
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 80 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ gormMongoVersion=7.3.0
grailsViewsVersion=2.3.2
assetPipelineVersion=3.3.4
elasticsearchVersion=7.17.9
alaSecurityLibsVersion=6.1.0
alaSecurityLibsVersion=6.2.0
mongoDBVersion=7.3.2
#22.x+ causes issues with mongo / GORM javax.validation.spi, might need grails 5
geoToolsVersion=21.5
Expand Down
7 changes: 4 additions & 3 deletions grails-app/conf/application.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -526,9 +526,6 @@ if (!security.cas.adminRole) {
if (!ecodata.use.uuids) {
ecodata.use.uuids = false
}
if (!userDetails.url) {
userDetails.url = "https://auth-test.ala.org.au/userdetails/"
}

if (!authGetKeyUrl) {
authGetKeyUrl = "https://m.ala.org.au/mobileauth/mobileKey/generateKey"
Expand All @@ -542,6 +539,10 @@ ecodata.documentation.exampleProjectUrl = 'http://ecodata-test.ala.org.au/ws/act
// Used by ParatooService to sync available protocols
paratoo.core.baseUrl = 'https://merit-test.core-api.paratoo.tern.org.au/api'

auth.baseUrl = 'https://auth-test.ala.org.au'
userDetails.web.url = "${auth.baseUrl}/userdetails/"
userDetails.api.url = "${auth.baseUrl}/userdetails/userDetails/"

if (!grails.cache.ehcache) {
grails {
cache {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
package au.org.ala.ecodata

import au.org.ala.ecodata.reporting.ManagementUnitXlsExporter
import au.org.ala.ecodata.reporting.XlsExporter
import org.apache.http.HttpStatus

import java.text.ParseException
import java.time.Instant


@RequireApiKey
class ManagementUnitController {

Expand Down Expand Up @@ -98,24 +90,6 @@ class ManagementUnitController {
respond managementUnitService.managementUnitSiteMap(ids)
}


/**
* startDate and endDate need to be ISO 8601
*
* Get reports of all management units in a given period
*/
def generateReportsInPeriod(){
try{
Map message = managementUnitService.generateReportsInPeriods(params.startDate, params.endDate, params.reportDownloadBaseUrl, params.senderEmail, params.systemEmail,params.email,params.getBoolean("summaryFlag", false))
respond(message, status:200)
}catch ( ParseException e){
def message = [message: 'Error: You need to provide startDate and endDate in the format of ISO 8601']
respond(message, status:HttpStatus.SC_NOT_ACCEPTABLE)
}catch(Exception e){
def message = [message: 'Fatal: ' + e.message]
respond(message, status:HttpStatus.SC_NOT_ACCEPTABLE)
}
}
/**
* Get financial years of managment unit reports cover
* @return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ package au.org.ala.ecodata
import grails.converters.JSON

import static au.org.ala.ecodata.ElasticIndex.DEFAULT_INDEX

/**
* Exposes web services to perform CRUD operations on an organisation.
*/
class OrganisationController {

static responseFormats = ['json', 'xml']
OrganisationService organisationService
ElasticSearchService elasticSearchService

Expand Down Expand Up @@ -96,7 +95,6 @@ class OrganisationController {
}
}


private Map buildParams(Map params) {

Map values = [:]
Expand Down
22 changes: 20 additions & 2 deletions grails-app/controllers/au/org/ala/ecodata/ParatooController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,26 @@ class ParatooController {
}

@PUT
@Path("/projects")
def updateProjectSites(String id) {
@Path("/projects/{id}")
@SecurityRequirements([@SecurityRequirement(name = "jwt"), @SecurityRequirement(name = "openIdConnect"), @SecurityRequirement(name = "oauth")])
@Operation(
method = "PUT",
responses = [
@ApiResponse(responseCode = "200", description = "Updated project", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Map.class))),
@ApiResponse(responseCode = "403", description = "Forbidden"),
@ApiResponse(responseCode = "500", description = "Internal server error")
],
requestBody = @RequestBody(
description = "Project sites to update",
required = true,
content = @Content(
mediaType = 'application/json',
schema = @Schema(implementation = Map.class)
)
),
tags = "Org Interface"
)
def updateProjectSites(@Parameter(name = "id", description = "Project id", required = true, in = ParameterIn.PATH, schema = @Schema(type = "string"))String id) {
String userId = userService.currentUserDetails.userId
List projects = paratooService.userProjects(userId)
ParatooProject project = projects?.find { it.id == id }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package au.org.ala.ecodata

import grails.converters.JSON
import org.grails.web.json.JSONObject
import org.apache.http.HttpStatus

import java.text.ParseException

class ReportController {

static responseFormats = ['json', 'xml']
def reportingService
ReportService reportService

def get(String id) {
respond reportingService.get(id, false)
Expand Down Expand Up @@ -89,4 +91,23 @@ class ReportController {

render reportingService.aggregateReports(params.searchCriteria, params.reportConfig) as JSON
}

/**
* startDate and endDate need to be ISO 8601
*
* Get reports of all management units in a given period
*/
@RequireApiKey
def generateReportsInPeriod(){
try{
Map message = reportService.generateReportsInPeriods(params.startDate, params.endDate, params.reportDownloadBaseUrl, params.senderEmail, params.systemEmail,params.email,params.getBoolean("summaryFlag", false), params.entity, params.hubId)
respond(message, status:200)
}catch ( ParseException e){
def message = [message: 'Error: You need to provide startDate and endDate in the format of ISO 8601']
respond(message, status: HttpStatus.SC_NOT_ACCEPTABLE)
}catch(Exception e){
def message = [message: 'Fatal: ' + e.message]
respond(message, status:HttpStatus.SC_NOT_ACCEPTABLE)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ class UrlMappings {


"/ws/report/runReport"(controller:"report", action:"runReport")
"/ws/report/generateReportsInPeriod"(controller:"report", action:"generateReportsInPeriod")

"/ws/project/findByName"(controller: "project"){ action = [GET:"findByName"] }
"/ws/project/importProjectsFromSciStarter"(controller: "project", action: "importProjectsFromSciStarter")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,45 +192,6 @@ class ManagementUnitService {
return [count: countOfReports, downloadId: downloadId]
}

/**
*
* @param startDate
* @param endDate
* @param reportDownloadBaseUrl Base url of downloading generated report
* @param senderEmail
* @param systemEmail
* @param receiverEmail
* @return
*/
Map generateReportsInPeriods(String startDate, String endDate, String reportDownloadBaseUrl, String senderEmail, String systemEmail, String receiverEmail, boolean isSummary ){
List<Map> reports = getReportingActivities(startDate,endDate)
int countOfReports = reports.sum{it.activities?.count{it.progress!=Activity.PLANNED}}

Map params = [:]
params.fileExtension = "xlsx"
params.reportDownloadBaseUrl = reportDownloadBaseUrl
params.senderEmail = senderEmail
params.systemEmail = systemEmail
params.email = receiverEmail

Closure doDownload = { File file ->
XlsExporter exporter = new XlsExporter(file.absolutePath)
ManagementUnitXlsExporter muXlsExporter = new ManagementUnitXlsExporter(exporter)
muXlsExporter.export(reports, isSummary)
exporter.sizeColumns()
exporter.save()
}
String downloadId = downloadService.generateReports(params, doDownload)
Map message =[:]
if (countOfReports>0){
message = [message:"Your will receive an email notification when report is generated", details:downloadId]
}else{
message = [message:"Your download will be emailed to you when it is complete. <p> WARNING, the period you requested may not have reports.", details: downloadId]
}
return message
}


/**
* Get reports of all management units in a period
*
Expand Down
38 changes: 34 additions & 4 deletions grails-app/services/au/org/ala/ecodata/OrganisationService.groovy
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package au.org.ala.ecodata


import com.mongodb.client.model.Filters
import grails.validation.ValidationException
import org.bson.conversions.Bson

import static au.org.ala.ecodata.Status.*
import static au.org.ala.ecodata.Status.DELETED

/**
* Works with Organisations, mostly CRUD operations at this point.
Expand All @@ -18,6 +17,8 @@ class OrganisationService {
static transactional = 'mongo'

def commonService, projectService, userService, permissionService, documentService, collectoryService, messageSource, emailService, grailsApplication
ReportingService reportingService
ActivityService activityService

def get(String id, levelOfDetail = [], includeDeleted = false) {
Organisation organisation
Expand Down Expand Up @@ -174,17 +175,46 @@ class OrganisationService {
* significant memory and performance overhead when dealing with so many entities
* at once.
* @param action the action to be performed on each Organisation.
* @param filters list of filters
*/
void doWithAllOrganisations(Closure action) {
void doWithAllOrganisations(Closure action, List<Filters> filters = []) {
// Due to various memory & performance issues with GORM mongo plugin 1.3, this method uses the native API.
def collection = Organisation.getCollection()
//DBObject siteQuery = new QueryBuilder().start('status').notEquals(DELETED).get()
Bson query = Filters.ne("status", DELETED);
Bson query = Filters.ne("status", DELETED)
filters.add(query)
query = Filters.and(filters)
def results = collection.find(query).batchSize(100)

results.each { dbObject ->
action.call(dbObject)
}
}

/**
* Get reports of all management units in a period
*
* @param start
* @param end
* @param hubId
* @return
*/
List<Map> getReportingActivities (String startDate, String endDate, String hubId) {
List<Map> organisationDetails = []
doWithAllOrganisations({ org ->
List<Report> reports = reportingService.search([organisationId: org.organisationId, dateProperty:'toDate', startDate:startDate, endDate:endDate])

List<Map> activities = activityService.search([activityId:reports.activityId], ['all'])

Map result = new HashMap(org)
result.reports = reports
result.activities = activities

organisationDetails << result

}, [Filters.eq("hubId", hubId)])

organisationDetails
}

}
63 changes: 63 additions & 0 deletions grails-app/services/au/org/ala/ecodata/ReportService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import static au.org.ala.ecodata.ElasticIndex.HOMEPAGE_INDEX
*/
@Slf4j
class ReportService {
static final String MU = 'managementUnit', ORG = 'organisation'

ActivityService activityService
ElasticSearchService elasticSearchService
Expand All @@ -26,6 +27,9 @@ class ReportService {
MetadataService metadataService
UserService userService
AuthService authService
DownloadService downloadService
ManagementUnitService managementUnitService
OrganisationService organisationService

def findScoresByLabel(List labels) {
Score.findAllByLabelInList(labels)
Expand Down Expand Up @@ -463,4 +467,63 @@ class ReportService {
List<String> activityIds = Report.findAllByManagementUnitIdInList(muIds.toList()).activityId
Date[] period = activityService.getPeriod(activityIds)
}

/**
* Generate report for entity
* @param startDate
* @param endDate
* @param reportDownloadBaseUrl Base url of downloading generated report
* @param senderEmail
* @param systemEmail
* @param receiverEmail
* @param entity managementUnit or organisation
* @param hubId
* @return
*/
Map generateReportsInPeriods(String startDate, String endDate, String reportDownloadBaseUrl, String senderEmail, String systemEmail, String receiverEmail, boolean isSummary, String entity, String hubId ){
List<Map> reports
switch (entity) {
case ORG:
reports = organisationService.getReportingActivities(startDate, endDate, hubId)
break
case MU:
default:
reports = managementUnitService.getReportingActivities(startDate, endDate)
break
}

int countOfReports = reports ? reports.sum{it.activities?.count{it.progress!=Activity.PLANNED}} : 0

Map params = [:]
params.fileExtension = "xlsx"
params.reportDownloadBaseUrl = reportDownloadBaseUrl
params.senderEmail = senderEmail
params.systemEmail = systemEmail
params.email = receiverEmail

Closure doDownload = { File file ->
XlsExporter exporter = new XlsExporter(file.absolutePath)
switch (entity) {
case ORG:
OrganisationXlsExporter orgXlsExporter = new OrganisationXlsExporter(exporter, [], [:])
orgXlsExporter.export(reports, isSummary)
break
case MU:
default:
ManagementUnitXlsExporter muXlsExporter = new ManagementUnitXlsExporter(exporter)
muXlsExporter.export(reports, isSummary)
break
}
exporter.sizeColumns()
exporter.save()
}
String downloadId = downloadService.generateReports(params, doDownload)
Map message =[:]
if (countOfReports>0){
message = [message:"Your will receive an email notification when report is generated", details:downloadId]
}else{
message = [message:"Your download will be emailed to you when it is complete. <p> WARNING, the period you requested may not have reports.", details: downloadId]
}
return message
}
}
Loading

0 comments on commit 24e62dc

Please sign in to comment.