Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AtlasOfLivingAustralia/fieldcapture#3004 #889

Merged
merged 2 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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