Skip to content

Commit

Permalink
Merge pull request #3434 from AtlasOfLivingAustralia/feature/issue3429
Browse files Browse the repository at this point in the history
Feature/issue3429
  • Loading branch information
chrisala authored Feb 6, 2025
2 parents 938eb04 + 77e8dc3 commit 05d3386
Show file tree
Hide file tree
Showing 15 changed files with 111 additions and 60 deletions.
44 changes: 15 additions & 29 deletions forms/other/regionalCapacityServicesReportV3.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,18 @@
{
"target": "targetIndigenousParticipationPercentage",
"source-path": "periodTargets.targetIndigenousParticipationPercentage"
},
{
"target": "reportedFundingExcludingThisReport",
"source-path": "reportedFundingExcludingThisReport"
}
],
"merge": {
"targetIndigenousParticipationPercentage": {
"replaceExisting": true
},
"reportedFundingExcludingThisReport": {
"replaceExisting": true
}
}
},
Expand Down Expand Up @@ -60,6 +67,10 @@
}
],
"dataModel": [
{
"name": "reportedFundingExcludingThisReport",
"dataType": "number"
},
{
"name": "governanceAndFinancialFrameworksOnTrack",
"dataType": "text",
Expand Down Expand Up @@ -242,7 +253,7 @@
},
{
"param": {
"expression": "organisationPanelProjectValue",
"expression": "organisationPanelProjectValue-reportedFundingExcludingThisReport",
"type": "computed"
},
"rule": "max",
Expand Down Expand Up @@ -639,18 +650,6 @@
}
]
},
{
"type": "row",
"items": [
{
"css": "span7",
"preLabel": "Target Workforce Performance % this reporting period",
"source": "targetIndigenousParticipationPercentage",
"type": "number",
"readonly": true
}
]
},
{
"type": "row",
"items": [
Expand Down Expand Up @@ -679,25 +678,12 @@
"items": [
{
"css": "span7",
"preLabel": "Supply Chain Performance to date",
"source": "supplyChainPerformancePercentage",
"type": "number",
"helpText": "Supply chain performance to date (note this is a cumulative measure over the life of the contract consistent with the approach used by NIAA measuring indigenous participation. Performance to date should meet or exceed target performance by the end of the Deed period)"
}
]
},
{
"type": "row",
"items": [
{
"css": "span7",
"preLabel": "Target supply chain performance at end of Deed period",
"source": "targetIndigenousProcurementPercentage",
"type": "number",
"readonly": true
"source": "To check how your performance to date against the agreed targets, please click on the dashboard tab after closing the report",
"type": "literal"
}
]
},

{
"type": "row",
"items": [
Expand Down
2 changes: 1 addition & 1 deletion grails-app/assets/javascripts/organisation.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ EditOrganisationViewModel = function(props, options) {
OrganisationPageViewModel = function (props, options) {
var self = this;
_.extend(self, new OrganisationViewModel(props, options));

self.areTargetsAndFundingEditable = options.areTargetsAndFundingEditable;
var tabs = {
'about': {
initialiser: function() {
Expand Down
9 changes: 6 additions & 3 deletions grails-app/assets/javascripts/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ function OrganisationDetailsViewModel(o, organisation, budgetHeaders, allService
var period = budgetHeaders,
serviceIds = o.services && o.services.serviceIds || [],
targets = o.services && o.services.targets || [];
self.services = new OrganisationServicesViewModel(serviceIds, config.services, targets, budgetHeaders);
self.areTargetsAndFundingEditable = config.areTargetsAndFundingEditable;
self.services = new OrganisationServicesViewModel(serviceIds, config.services, targets, budgetHeaders, {areTargetsEditable:config.areTargetsAndFundingEditable});
self.funding = new BudgetViewModel(o.funding, budgetHeaders);
self.funding.isEditable = config.areTargetsAndFundingEditable;

function clearHiddenFields(jsData) {

};
Expand Down Expand Up @@ -34,13 +37,13 @@ function OrganisationDetailsViewModel(o, organisation, budgetHeaders, allService
* @param outputTargets The current organisation targets
* @param periods An array of periods, each of which require a target to be set
*/
function OrganisationServicesViewModel(serviceIds, allServices, outputTargets, periods) {
function OrganisationServicesViewModel(serviceIds, allServices, outputTargets, periods, options) {
var self = this,
OPERATION_SUM = "SUM",
OPERATION_AVG = "AVG",
operation = OPERATION_AVG;

self.isProjectDetailsLocked = ko.observable(false);
self.areTargetsEditable = options.areTargetsEditable;

allServices = _.sortBy(allServices || [], function (service) {
return service.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class OrganisationController {
dashboardData = organisationService.scoresForOrganisation(organisation, scores?.collect{it.scoreId}, !hasEditorAccess)
}
boolean showTargets = userService.userIsSiteAdmin() && services && targetPeriods

boolean targetsEditable = userService.userIsAlaOrFcAdmin()
List reportOrder = null
if (reportingVisible) {
// TODO change me to use the configuration once it's been decided how that
Expand Down Expand Up @@ -114,7 +114,7 @@ class OrganisationController {
projects : [label: 'Reporting', template:"/shared/projectListByProgram", visible: reportingVisible, stopBinding:true, default:reportingVisible, type: 'tab', reports:organisation.reports, adHocReportTypes:adHocReportTypes, reportOrder:reportOrder, hideDueDate:true, displayedPrograms:projectGroups.displayedPrograms, reportsFirst:true, declarationType:SettingPageType.RDP_REPORT_DECLARATION],
sites : [label: 'Sites', visible: reportingVisible, type: 'tab', stopBinding:true, projectCount:organisation.projects?.size()?:0, showShapefileDownload:adminVisible],
dashboard : [label: 'Dashboard', visible: reportingVisible, stopBinding:true, type: 'tab', template:'dashboard', reports:dashboardReports, dashboardData:dashboardData],
admin : [label: 'Admin', visible: adminVisible, type: 'tab', template:'admin', showEditAnnoucements:showEditAnnoucements, availableReportCategories:availableReportCategories, targetPeriods:targetPeriods, services: services, showTargets:showTargets]]
admin : [label: 'Admin', visible: adminVisible, type: 'tab', template:'admin', showEditAnnoucements:showEditAnnoucements, availableReportCategories:availableReportCategories, targetPeriods:targetPeriods, services: services, showTargets:showTargets, targetsEditable:targetsEditable]]

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ class ProjectController {
}

model.context = new HashMap(project)
model.context.putAll(reportData.getContextData(project, model.report))
model.context.putAll(reportData.getContextData(project, model.report, model.activity))
model.returnTo = g.createLink(action:'exitReport', id:projectId, params:[reportId:reportId])
model.contextViewUrl = g.createLink(action:'index', id:projectId)
model.reportHeaderTemplate = '/project/rlpProjectReportHeader'
Expand Down
10 changes: 10 additions & 0 deletions grails-app/services/au/org/ala/merit/MetadataService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,16 @@ class MetadataService {
})
}

/**
* Returns a Map cantaining the properties of a Score identified by a supplied name.
* A score name is a unique identifier that is human readable and stable between test/staging/production
* environments.
* @param name The name of the Score of interest.
*/
Map findScoreByName(String name) {
getScores(false).find { it.name == name }
}

List<Map> getScores(boolean includeConfig) {
cacheService.get("scores-${includeConfig}", {
String url = grailsApplication.config.getProperty('ecodata.baseUrl') + "metadata/scores"
Expand Down
2 changes: 1 addition & 1 deletion grails-app/views/organisation/_funding.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<tr>
<!-- ko foreach: costs -->
<td class="budget-amount">
<input type="number" class="form-control form-control-sm" data-bind="value: dollar, numeric: $root.number, disable: $root.isProjectDetailsLocked()" data-validation-engine="validate[custom[number],min[0]"/>
<input type="number" class="form-control form-control-sm" data-bind="value: dollar, numeric: $root.number, enable: $parents[1].isEditable" data-validation-engine="validate[custom[number],min[0]"/>
</td>
<!-- /ko -->
</tr>
Expand Down
10 changes: 5 additions & 5 deletions grails-app/views/organisation/_serviceTargets.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
<tr>
<td class="index"><span data-bind="text:$index()+1"></span></td>
<td class="service">
<select class="form-control form-control-sm" data-bind="options: selectableServices, optionsText:'name', optionsValue:'id', value:serviceId, disable: $root.isProjectDetailsLocked()"
<select class="form-control form-control-sm" data-bind="options: selectableServices, optionsText:'name', optionsValue:'id', value:serviceId, enable: $parent.areTargetsEditable"
data-validation-engine="validate[required]"></select>
</td>
<td class="score">
<select class="form-control form-control-sm" data-bind="options: selectableScores, optionsText:'label', optionsValue:'scoreId', value:scoreId, disable: $root.isProjectDetailsLocked()"
<select class="form-control form-control-sm" data-bind="options: selectableScores, optionsText:'label', optionsValue:'scoreId', value:scoreId, enable: $parent.areTargetsEditable"
data-validation-engine="validate[required]"></select>
</td>
<td class="budget-cell">
Expand All @@ -45,7 +45,7 @@
<g:if test="${showTargetDate}">
<td class="target-date">
<div class="input-group">
<input class="form-control form-control-sm" data-bind="datepicker:targetDate.date, disable: $root.isProjectDetailsLocked()" type="text" size="16" data-validation-engine="validate[required]">
<input class="form-control form-control-sm" data-bind="datepicker:targetDate.date, enable: $parent.areTargetsEditable" type="text" size="16" data-validation-engine="validate[required]">
<div class="input-group-append open-datepicker">
<span class="input-group-text">
<i class="fa fa-th ">&nbsp;</i>
Expand All @@ -58,7 +58,7 @@
<!-- ko foreach: periodTargets -->
<td class="budget-cell">
<input class="form-control form-control-sm" type="number"
data-bind="value: target, disable: $root.isProjectDetailsLocked()"
data-bind="value: target, enable: $parents[1].areTargetsEditable"
data-validation-engine="validate[custom[number],min[0]]"/>
</td>
<!-- /ko -->
Expand All @@ -68,4 +68,4 @@
</table>
<!-- /ko -->
<!-- /ko -->
<button class="btn btn-sm btn-primary" data-bind="click: saveCustomFields">Save changes</button>
<button class="btn btn-sm btn-primary" data-bind="click: saveCustomFields, enable:areTargetsAndFundingEditable">Save changes</button>
2 changes: 2 additions & 0 deletions grails-app/views/organisation/index.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,14 @@
var availableReportCategories = <fc:modelAsJavascript model="${content.admin?.availableReportCategories}"/>;
var services = <fc:modelAsJavascript model="${content.admin?.services}"/>;
var targetPeriods = <fc:modelAsJavascript model="${content.admin?.targetPeriods}"/>;
var areTargetsAndFundingEditable = ${Boolean.valueOf(content.admin?.targetsEditable)};
var config = _.extend({
reportingConfigSelector:'#reporting-config form',
availableReportCategories:availableReportCategories,
targetPeriods: targetPeriods,
services: services,
organisationDetailsSelector: '#organisation-details',
areTargetsAndFundingEditable: areTargetsAndFundingEditable

}, fcConfig);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ abstract class EditOrViewReportCommand implements Validateable {

ReportLifecycleListener listener = reportService.reportLifeCycleListener(model.report)
if (listener) {
model.context.putAll(listener.getContextData(entity, model.report))
model.context.putAll(listener.getContextData(entity, model.report, model.activity))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class NHTOutputReportLifecycleListener extends ReportLifecycleListener {
boolean containsEntityReferences() {
true
}
Map getContextData(Map project, Map report) {
Map getContextData(Map project, Map report, Map activity) {
// Side effect - filter data sets.
List eligibleDataSets = project.custom?.dataSets?.findAll {
// This is a side effect and a workaround for the problem that selected outcomes
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package au.org.ala.merit.reports

import au.org.ala.merit.MetadataService
import au.org.ala.merit.OrganisationService
import groovy.util.logging.Slf4j
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -10,11 +11,17 @@ class RegionalCapacityServicesReportLifecycleListener extends ReportLifecycleLis
@Autowired
OrganisationService organisationService

Map getContextData(Map organisation, Map report) {
@Autowired
MetadataService metadataService

private static String TOTAL_REPORTED_VALUE_SCORE_NAME = 'totalValueServicesContractedToFirstNations'

Map getContextData(Map organisation, Map report, Map activity) {
List outputTargets = organisation.custom?.details?.services?.targets
Map periodTargets = getTargetsForReportPeriod(report, outputTargets)
def funding = getFundingForPeriod(organisation, report)
[periodTargets:periodTargets, totalContractValue:funding]
def reportedFundingExcludingThisReport = getReportedFundingToDate(organisation, activity)
[periodTargets:periodTargets, totalContractValue:funding, reportedFundingExcludingThisReport:reportedFundingExcludingThisReport]
}

private static def getFundingForPeriod(Map organisation, Map report) {
Expand All @@ -29,4 +36,24 @@ class RegionalCapacityServicesReportLifecycleListener extends ReportLifecycleLis
index >= 0 ? organisation.custom?.details?.funding?.rows[0].costs[index].dollar : 0

}

private double getReportedFundingToDate(Map organisation, Map activity) {
Map score = metadataService.findScoreByName(TOTAL_REPORTED_VALUE_SCORE_NAME)
if (!score) {
log.error("No score found for organisation ${organisation.id} and score name ${TOTAL_REPORTED_VALUE_SCORE_NAME}")
return 0
}
List scoreData = organisationService.scoresForOrganisation(organisation, [score.scoreId], false)

double firstNationsServicesTotal = 0
Map firstNationsServicesScore = scoreData[0]
if (firstNationsServicesScore) {
firstNationsServicesTotal = firstNationsServicesScore.result?.result ?: 0
String amountReportedThisPeriod = activity?.outputs?[0]?.data?.servicesContractedValueFirstNations
double reportedAmountThisReport = amountReportedThisPeriod ? Double.valueOf(amountReportedThisPeriod) : 0

firstNationsServicesTotal -= reportedAmountThisReport
}
return firstNationsServicesTotal
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ReportLifecycleListener {
@Autowired
MetadataService metadataService

Map getContextData(Map context, Map report) { [:] }
Map getContextData(Map context, Map report, Map activity) { [:] }
Map getOutputData(Map context, Map outputConfig, Map report) { [:] }
Map reportSaved(Map report, Map activityData) { [:] }
Map reportSubmitted(Map report, List reportActivityIds, Map reportOwner) { [:] }
Expand Down
Loading

0 comments on commit 05d3386

Please sign in to comment.