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

Feature/issue3011 #3012

Merged
merged 2 commits into from
Oct 23, 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
10 changes: 10 additions & 0 deletions grails-app/assets/javascripts/common-bs4.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,13 @@ ReportStatus = {
return status && status.toLowerCase() == this.CANCELLED;
}
}

PublicationStatus = {
PUBLISHED: 'published',
SUBMITTED: 'pendingApproval',
UNPUBLISHED: '',

isReadOnly: function(status) {
return status && status != this.UNPUBLISHED;
}
}
1 change: 1 addition & 0 deletions grails-app/assets/javascripts/sites.js
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,7 @@ var SitesViewModel = function(sites, map, mapFeatures, isUserEditor, projectId)
if (!site.type) {
site.type = 'worksArea';
}
site.readOnly = site.type == 'compound' || PublicationStatus.isReadOnly(site.publicationStatus);
return site;
});
self.selectedSiteIds = ko.computed(function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class ProjectController {
else if (template == RLP_TEMPLATE) {

// The RLP Project Template doesn't need site details or activities.
project.sites = new JSONArray(project.sites?.collect{new JSONObject([name:it.name, siteId:it.siteId, lastUpdated:it.lastUpdated, type:it.type, extent:[:]])} ?: [])
project.sites = new JSONArray(project.sites?.collect{new JSONObject([name:it.name, siteId:it.siteId, lastUpdated:it.lastUpdated, type:it.type, extent:[:], publicationStatus:it.publicationStatus])} ?: [])
project.remove('activities')
model.overview.template = 'rlpOverview'

Expand Down
10 changes: 5 additions & 5 deletions grails-app/controllers/au/org/ala/merit/SiteController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class SiteController {
flash.message = "Access denied: User does not have <b>editor</b> permission to edit site: ${id}"
redirect(controller:'home', action:'index')
} else {
if (result.site.type == SiteService.SITE_TYPE_COMPOUND) {
if (SiteService.isReadOnly(result.site)) {
redirect(action:'index', id:id)
}
result
Expand Down Expand Up @@ -174,7 +174,7 @@ class SiteController {
List siteIds = payload.siteIds

project?.sites?.each { site ->
if (site.type == SiteService.SITE_TYPE_COMPOUND) {
if (SiteService.isReadOnly(site)) {
siteIds.remove(site.siteId)
}
}
Expand All @@ -196,7 +196,7 @@ class SiteController {
return
}
Map site = siteService.get(id)
if (!projectService.canUserEditProject(userService.getCurrentUserId(), projectId) || site.type == SiteService.SITE_TYPE_COMPOUND) {
if (!projectService.canUserEditProject(userService.getCurrentUserId(), projectId) || SiteService.isReadOnly(site)) {
render status:403, text: "Access denied: User does not have permission to edit sites for project: ${projectId}"
return
}
Expand All @@ -214,7 +214,7 @@ class SiteController {
def ajaxDelete(String id) {
// permissions check
Map site = siteService.get(id)
if (!isUserMemberOfSiteProjects(site) || site.type == SiteService.SITE_TYPE_COMPOUND) {
if (!isUserMemberOfSiteProjects(site) || SiteService.isReadOnly(site)) {
render status:403, text: "Access denied: User does not have permission to edit site: ${id}"
return
}
Expand All @@ -234,7 +234,7 @@ class SiteController {
log.debug("Updating site: " + id)
Map site = siteService.get(id)
// permissions check
if (!isUserMemberOfSiteProjects(site) || site.type == SiteService.SITE_TYPE_COMPOUND) {
if (!isUserMemberOfSiteProjects(site) || SiteService.isReadOnly(site)) {
render status:403, text: "Access denied: User does not have permission to edit site: ${id}"
return
}
Expand Down
3 changes: 2 additions & 1 deletion grails-app/services/au/org/ala/merit/ProjectService.groovy
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package au.org.ala.merit

import au.org.ala.merit.config.EmailTemplate
import au.org.ala.merit.PublicationStatus
import au.org.ala.merit.config.ProgramConfig
import au.org.ala.merit.config.ReportConfig
import au.org.ala.merit.reports.ReportGenerationOptions
Expand Down Expand Up @@ -606,7 +607,7 @@ class ProjectService {
// Some projects have extra stage reports after the end date due to legacy data so this checks we've got the last stage within the project dates
List validReports = project.reports?.findAll{it.fromDate < project.plannedEndDate ? it.fromDate : project.plannedStartDate}

List incompleteReports = (validReports?.findAll{it.publicationStatus != ReportService.REPORT_APPROVED && it.publicationStatus != ReportService.REPORT_CANCELLED})?:[]
List incompleteReports = (validReports?.findAll{PublicationStatus.requiresAction(it.publicationStatus)})?:[]

return incompleteReports.size() ==1 && incompleteReports[0].reportId == approvedReportId
}
Expand Down
11 changes: 3 additions & 8 deletions grails-app/services/au/org/ala/merit/ReportService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ import org.joda.time.Period
@Slf4j
class ReportService {

public static final String REPORT_APPROVED = 'published'
public static final String REPORT_SUBMITTED = 'pendingApproval'
public static final String REPORT_NOT_APPROVED = 'unpublished'
public static final String REPORT_CANCELLED = 'cancelled'

public static final int HOME_PAGE_IMAGE_SIZE = 500

public static final String REPORT_TYPE_SINGLE_ACTIVITY = 'Single'
Expand Down Expand Up @@ -168,11 +163,11 @@ class ReportService {
}

boolean excludesNotApproved(Map report) {
return report.publicationStatus == REPORT_SUBMITTED || report.publicationStatus == REPORT_APPROVED || report.publicationStatus == REPORT_CANCELLED
return PublicationStatus.isReadOnly(report.publicationStatus)
}

boolean isApproved(Map report) {
return report.publicationStatus == REPORT_APPROVED
return PublicationStatus.isApproved(report.publicationStatus)
}

List search(Map criteria) {
Expand Down Expand Up @@ -887,7 +882,7 @@ class ReportService {
Map filter = state?[type:'DISCRETE', property:'data.state']:[:]
Map config = [groups:filter, childAggregations: aggregations, label:'Performance assessment by state']

Map searchCriteria = [type:['Performance Management Framework - Self Assessment', 'Performance Management Framework - Self Assessment v2'], publicationStatus:REPORT_APPROVED, dateProperty:'toDate', 'startDate':(year-1)+'-07-01T10:00:00Z', 'endDate':year+'-07-01T10:00:00Z']
Map searchCriteria = [type:['Performance Management Framework - Self Assessment', 'Performance Management Framework - Self Assessment v2'], publicationStatus:PublicationStatus.APPROVED, dateProperty:'toDate', 'startDate':(year-1)+'-07-01T10:00:00Z', 'endDate':year+'-07-01T10:00:00Z']

String url = grailsApplication.config.getProperty('ecodata.baseUrl')+"report/runReport"

Expand Down
4 changes: 4 additions & 0 deletions grails-app/services/au/org/ala/merit/SiteService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class SiteService {
/** A site with the extent derived from the convex hull of a set of geojson features */
public static final String SITE_TYPE_COMPOUND = 'compound'

static isReadOnly(Map site) {
site?.type == SITE_TYPE_COMPOUND || PublicationStatus.isReadOnly(site.publicationStatus)
}

def projectsForSite(siteId) {
get(siteId)?.projects
}
Expand Down
6 changes: 3 additions & 3 deletions grails-app/views/site/_sitesList.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@
</thead>
<tbody data-bind="foreach: sites">
<tr>
<th><input type="checkbox" name="select-site" data-bind="checked:selected, enable:type != 'compound'"></th>
<th><input type="checkbox" name="select-site" data-bind="checked:selected, enable:!readOnly"></th>
<td>
<g:if test="${editable}">
<span>
<button type="button" data-bind="click:$root.editSite, visible:type != 'compound'" class="btn btn-sm btn-container"><i class="fa fa-edit" title="Edit ${wordForSite.capitalize()}"></i></button>
<button type="button" data-bind="click:$root.editSite, visible:!readOnly" class="btn btn-sm btn-container"><i class="fa fa-edit" title="Edit ${wordForSite.capitalize()}"></i></button>
<button type="button" data-bind="click:$root.viewSite" class="btn btn-sm btn-container"><i class="fa fa-eye" title="View ${wordForSite.capitalize()}"></i></button>
<button type="button" data-bind="click:$root.deleteSite, visible:type != 'compound'" class="btn btn-sm btn-container"><i class="fa fa-remove" title="Delete ${wordForSite.capitalize()}"></i></button>
<button type="button" data-bind="click:$root.deleteSite, visible:!readOnly" class="btn btn-sm btn-container"><i class="fa fa-remove" title="Delete ${wordForSite.capitalize()}"></i></button>
</span>
</g:if>
</td>
Expand Down
2 changes: 1 addition & 1 deletion grails-app/views/site/index.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

Site Actions:
<div class="btn-group">
<g:if test="${site.type != au.org.ala.merit.SiteService.SITE_TYPE_COMPOUND}">
<g:if test="${!au.org.ala.merit.SiteService.isReadOnly(site)}">
<g:link action="edit" id="${site.siteId}"><button type="button" class="btn btn-sm mr-1"><i class="fa fa-edit"></i> Edit Site</button></g:link>
</g:if>

Expand Down
22 changes: 22 additions & 0 deletions src/main/groovy/au/org/ala/merit/PublicationStatus.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package au.org.ala.merit

class PublicationStatus {
public static final String APPROVED = 'published'
public static final String SUBMITTED = 'pendingApproval'
public static final String NOT_APPROVED = 'unpublished'
public static final String CANCELLED = 'cancelled'

static boolean isReadOnly(publicationStatus) {
// A null/blank publication status is treated the same as a NOT_APPROVED status
publicationStatus == APPROVED || publicationStatus == SUBMITTED || publicationStatus == CANCELLED
}

static boolean isApproved(publicationStatus) {
publicationStatus == APPROVED
}

/** A status indicates the item requires further action when it is not yet approved or cancelled */
static boolean requiresAction(publicationStatus) {
publicationStatus != APPROVED && publicationStatus != CANCELLED
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package au.org.ala.merit.command
import au.org.ala.merit.ActivityService
import au.org.ala.merit.DateUtils
import au.org.ala.merit.ProjectService
import au.org.ala.merit.PublicationStatus
import au.org.ala.merit.ReportService
import au.org.ala.merit.SettingPageType
import au.org.ala.merit.SettingService
Expand Down Expand Up @@ -109,7 +110,7 @@ class Reef2050PlanActionReportCommand extends Reef2050PlanActionReportConfig imp
progress:ActivityService.PROGRESS_FINISHED]

if (approvedActivitiesOnly) {
searchCriteria.publicationStatus = ReportService.REPORT_APPROVED
searchCriteria.publicationStatus = PublicationStatus.APPROVED
}

Map resp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package au.org.ala.merit.command

import au.org.ala.merit.ActivityService
import au.org.ala.merit.DateUtils
import au.org.ala.merit.ReportService
import au.org.ala.merit.PublicationStatus
import au.org.ala.merit.reports.Reef2050PlanActionReportConfig
import grails.converters.JSON
import grails.validation.Validateable
Expand Down Expand Up @@ -41,7 +40,7 @@ class Reef2050PlanActionReportSummaryCommand implements Validateable{
[type : Reef2050PlanActionReportConfig.REEF_2050_PLAN_ACTION_REPORTING_2018_ACTIVITY_TYPE,
progress: ActivityService.PROGRESS_FINISHED]
if (approvedActivitiesOnly) {
searchCriteria.publicationStatus = ReportService.REPORT_APPROVED
searchCriteria.publicationStatus = PublicationStatus.APPROVED
}

List availableReports = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package au.org.ala.merit.reports

import au.org.ala.merit.DateUtils
import au.org.ala.merit.config.ReportConfig
import au.org.ala.merit.PublicationStatus
import org.apache.commons.logging.LogFactory
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.joda.time.Duration
import org.joda.time.Interval
import org.joda.time.Period
import org.joda.time.PeriodType
Expand All @@ -28,8 +28,6 @@ class ReportGenerator {
*/
private int DATE_FUDGE_FACTOR = 1

private static final String REPORT_NOT_APPROVED = 'unpublished'

/**
* Generates a list of reports according to the supplied configuration.
* @param reportConfig Describes the frequency and properties of generated reports.
Expand Down Expand Up @@ -122,7 +120,7 @@ class ReportGenerator {

if (end >= start) {
//validates the latest approved report to avoid creation of duplicate report
if (existingReports && existingReports[0].publicationStatus != REPORT_NOT_APPROVED) {
if (existingReports && existingReports[0].publicationStatus != PublicationStatus.NOT_APPROVED) {
log.info("Not regenerating report " + reportConfig.category + " to avoid creating duplicate reports")
} else {
Interval reportInterval = new Interval(start, end)
Expand Down
28 changes: 14 additions & 14 deletions src/test/groovy/au/org/ala/merit/ProjectServiceSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ class ProjectServiceSpec extends Specification implements ServiceUnitTest<Projec
def projectId = 'project1'
def newStartDate = '2015-06-01T00:00Z'
reportService.includesSubmittedOrApprovedReports(_) >> true
reportService.getReportsForProject(_) >> [[publicationStatus:ReportService.REPORT_APPROVED]]
reportService.getReportsForProject(_) >> [[publicationStatus:PublicationStatus.APPROVED]]
Map project = [projectId:projectId, planStatus:ProjectService.PLAN_NOT_APPROVED, plannedStartDate: '2015-07-01T00:00Z', plannedEndDate:'2016-12-31T00:00Z']
webService.getJson(_) >> project

Expand All @@ -497,9 +497,9 @@ class ProjectServiceSpec extends Specification implements ServiceUnitTest<Projec
def activityIds = ['a1', 'a2']
def stageReportDetails = [activityIds:activityIds, reportId:reportId, stage:'Stage 2', reason:reason]
reportService.getReportsForProject(projectId) >>[
[reportId:'r1', publicationStatus:ReportService.REPORT_APPROVED, name:'Stage 1', fromDate: '2015-07-01T00:00Z', toDate: '2016-01-01T00:00Z'],
[reportId:'r2', publicationStatus:ReportService.REPORT_NOT_APPROVED, name:'Stage 2', fromDate: '2016-01-01T00:00Z', toDate: '2017-01-01T00:00Z'],
[reportId:'r3', publicationStatus:ReportService.REPORT_CANCELLED, name:'Stage 3', fromDate: '2016-01-01T00:00Z', toDate: '2017-01-01T00:00Z']]
[reportId:'r1', publicationStatus:PublicationStatus.APPROVED, name:'Stage 1', fromDate: '2015-07-01T00:00Z', toDate: '2016-01-01T00:00Z'],
[reportId:'r2', publicationStatus:PublicationStatus.NOT_APPROVED, name:'Stage 2', fromDate: '2016-01-01T00:00Z', toDate: '2017-01-01T00:00Z'],
[reportId:'r3', publicationStatus:PublicationStatus.CANCELLED, name:'Stage 3', fromDate: '2016-01-01T00:00Z', toDate: '2017-01-01T00:00Z']]
webService.getJson(_) >> [projectId:projectId, planStatus:ProjectService.PLAN_NOT_APPROVED, plannedStartDate: '2015-07-01T00:00Z', plannedEndDate:'2016-12-31T00:00Z']

when:
Expand Down Expand Up @@ -797,7 +797,7 @@ class ProjectServiceSpec extends Specification implements ServiceUnitTest<Projec
Map project = [projectId:'p1', plannedStartDate: '2015-07-01T00:00Z', plannedEndDate:'2016-12-31T00:00Z', planStatus:ProjectService.PLAN_APPROVED]

webService.getJson(_) >> project
reportService.getReportsForProject(project.projectId) >> [[reportId:'r1', publicationStatus:ReportService.REPORT_NOT_APPROVED, fromDate:project.plannedStartDate, toDate:project.plannedEndDate]]
reportService.getReportsForProject(project.projectId) >> [[reportId:'r1', publicationStatus:PublicationStatus.NOT_APPROVED, fromDate:project.plannedStartDate, toDate:project.plannedEndDate]]
reportService.firstReportWithDataByCriteria(_, _) >> null

when:
Expand All @@ -814,7 +814,7 @@ class ProjectServiceSpec extends Specification implements ServiceUnitTest<Projec
project.reports = [r1]
reportService.firstReportWithDataByCriteria(_, _) >> r1

boolean submittedOrApproved = (reportStatus == ReportService.REPORT_SUBMITTED || reportStatus == ReportService.REPORT_APPROVED)
boolean submittedOrApproved = (reportStatus == PublicationStatus.SUBMITTED || reportStatus == PublicationStatus.APPROVED)
webService.getJson(_) >> project
reportService.getReportsForProject(project.projectId) >> [r1]
reportService.excludesNotApproved(_) >> submittedOrApproved
Expand All @@ -827,14 +827,14 @@ class ProjectServiceSpec extends Specification implements ServiceUnitTest<Projec

where:
reportStatus | date | valid
ReportService.REPORT_APPROVED | '2015-07-01T00:00Z' | true
ReportService.REPORT_APPROVED | '2015-08-01T00:00Z' | true
ReportService.REPORT_APPROVED | '2016-01-01T00:00Z' | false
ReportService.REPORT_APPROVED | '2015-04-01T00:00Z' | false
ReportService.REPORT_SUBMITTED | '2015-07-01T00:00Z' | true
ReportService.REPORT_SUBMITTED | '2015-08-01T00:00Z' | true
ReportService.REPORT_SUBMITTED | '2016-01-01T00:00Z' | false
ReportService.REPORT_SUBMITTED | '2015-04-01T00:00Z' | false
PublicationStatus.APPROVED | '2015-07-01T00:00Z' | true
PublicationStatus.APPROVED | '2015-08-01T00:00Z' | true
PublicationStatus.APPROVED | '2016-01-01T00:00Z' | false
PublicationStatus.APPROVED | '2015-04-01T00:00Z' | false
PublicationStatus.SUBMITTED | '2015-07-01T00:00Z' | true
PublicationStatus.SUBMITTED | '2015-08-01T00:00Z' | true
PublicationStatus.SUBMITTED | '2016-01-01T00:00Z' | false
PublicationStatus.SUBMITTED | '2015-04-01T00:00Z' | false
}

def "if there is an empty report before the first report with data, we should be allowed to change the start date as if the first report with data was the only report"(date, valid) {
Expand Down
Loading
Loading