package net.techreadiness.plugin.action.reports.device.progress; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import javax.inject.Inject; import net.techreadiness.annotation.CoreSecured; import net.techreadiness.persistence.criteriaquery.QueryResult; import net.techreadiness.plugin.action.reports.GeoChartBean; import net.techreadiness.plugin.action.reports.ReportAction; import net.techreadiness.plugin.action.reports.ReportExport; import net.techreadiness.plugin.action.reports.ReportExportCsv; import net.techreadiness.plugin.action.reports.ReportExportPdf; import net.techreadiness.plugin.action.reports.ReportItemProvider; import net.techreadiness.plugin.action.reports.ReportItemProvider.ExportType; import net.techreadiness.plugin.action.task.snapshot.SnapshotComparator; import net.techreadiness.plugin.service.SnapshotWindowService; import net.techreadiness.plugin.service.object.SnapshotWindow; import net.techreadiness.plugin.service.reports.ReportsService; import net.techreadiness.security.CorePermissionCodes; import net.techreadiness.service.ServiceContext; import net.techreadiness.service.object.Org; import net.techreadiness.service.object.OrgPart; import net.techreadiness.service.object.Scope; import net.techreadiness.ui.tags.datagrid.DataGridState; import net.techreadiness.ui.util.ConversationScoped; import org.apache.commons.lang3.StringUtils; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.springframework.beans.factory.annotation.Qualifier; import com.google.common.collect.Lists; import com.google.common.collect.Sets; public class DeviceProgressReportAction extends ReportAction { private static final long serialVersionUID = 1L; private String orgCode; private String stateCode; private String stateName; private GeoChartBean geoChart; private Set<SnapshotWindow> snapshots; private Org currentOrg; private boolean dualConsortium; @Inject private SnapshotWindowService snapshotService; @Inject private ReportsService reportService; @Inject @Qualifier("DeviceProgressItemProvider") private ReportItemProvider reportItemProvider; @ConversationScoped(value = "deviceProgressDataGridState") private DataGridState<?> reportGrid; @CoreSecured({ CorePermissionCodes.READY_CUSTOMER_PROGESS_DEVICE_RPT }) @Action(value = "deviceProgress", results = { @Result(name = "report", location = "/net/techreadiness/plugin/action/reports/device/progress/report.jsp") }) public String deviceProgress() throws Exception { getData(); buildBreadcrumbs(currentOrg, consortium, "deviceProgress"); return "report"; } private void getData() throws Exception { ServiceContext context = getServiceContext(); // check if we are passed an org code // we should get this passed to us on every request outside the initial request (clicking on tab) if (orgCode == null || orgCode.equals("")) { Org org = context.getOrg(); orgCode = org.getCode(); } currentOrg = orgService.getByCode(context, orgCode); if (currentOrg == null || !userService.hasAccessToOrg(context, context.getUserId(), currentOrg.getOrgId())) { if (currentOrg == null) { throw new Exception("Org could not be found: " + orgCode); } throw new Exception("User(" + context.getUserId() + ") doesn't have access to org (" + currentOrg.getOrgId() + ")"); } // get previous org off the session, if different, reset paging Map<String, Object> session = getSession(); if (session.get("prevOrgDevice") == null || !currentOrg.getId().equals(session.get("prevOrgDevice"))) { reportGrid.setPage(1); reportGrid.setPageSize(10); } session.put("prevOrgDevice", currentOrg.getId()); // check if user has access to dual consortium dualConsortium = userService.hasPermission(context, CorePermissionCodes.CORE_CUSTOMER_CHANGE_GLOBAL_SCOPE); // if true, check to make sure the current org has access to both consortiums List<OrgPart> orgParts = orgPartService.findOrgPartsForOrg(context, currentOrg.getOrgId()); if (dualConsortium) { dualConsortium = orgParts != null && orgParts.size() > 1; } // if consortium is null, set consortium to the consortium in the service context if (consortium == null) { consortium = Consortium.getConsortium(context.getScope().getCode()); } // get the consortiums scope object Scope consortiumScope = scopeService.getByScopePath(consortium.path); // set the appropriate data for the report item provider reportItemProvider.setConsortium(consortiumScope); snapshots = Sets.newTreeSet(new SnapshotComparator()); snapshots.addAll(snapshotService.findActiveSnapshots(context, consortiumScope.getScopeId())); List<Long> snapshotWindowIds = Lists.newArrayList(); for (SnapshotWindow snapshot : snapshots) { snapshotWindowIds.add(snapshot.getSnapshotWindowId()); } reportItemProvider.setSnapshotWindows(snapshots); reportItemProvider.setSnapshotWindow(getCurrentSnapshotWindow()); reportItemProvider.setOrg(currentOrg); reportItemProvider.setMinimumRecommendedFlag(getMinimumRecommendedFlag()); if (currentOrg.getOrgTypeName().equals("Readiness")) { // query the map data QueryResult<Map<String, String>> result = reportService.retrieveProgressDataForChildOrgs(snapshotWindowIds, currentOrg.getOrgId(), getMinimumRecommendedFlag(), true, null, null); // put state data into geochart geoChart = new GeoChartBean(); geoChart.addColor("#463de4"); geoChart.setHoverLabel("Consortium"); geoChart.setWidth(285); geoChart.setHeight(175); for (Map<String, String> data : result.getRows()) { geoChart.addBooleanData(data.get("orgCode"), StringUtils.remove(data.get("orgName"), "(" + data.get("localOrgCode") + ")"), data.get("localOrgCode"), consortium.toString()); } } else if (currentOrg.getOrgTypeName().equals("State")) { // set state code and name (needed for image on page) stateCode = currentOrg.getLocalCode().toUpperCase(); stateName = currentOrg.getName(); } else if (currentOrg.getOrgTypeName().equals("District")) { Org state = orgService.getById(context, currentOrg.getParentOrgId()); // set state code and name (needed for image on page) stateCode = state.getLocalCode().toUpperCase(); stateName = state.getName(); } else if (currentOrg.getOrgTypeName().equals("School")) { Org district = orgService.getById(context, currentOrg.getParentOrgId()); Org state = orgService.getById(context, district.getParentOrgId()); // set state code and name (needed for image on page) stateCode = state.getLocalCode().toUpperCase(); stateName = state.getName(); } } @Override protected ReportExport getReportExport(ExportType type) throws Exception { // populate reportItemProvider setFileName("DeviceProgress"); getData(); List<String> columnLabels = null, columnKeys = null; List<Boolean> useConditionalStyles = null; columnLabels = Lists.newArrayList("Organization", "Org Code"); columnKeys = Lists.newArrayList("orgName", "orgCode"); useConditionalStyles = Lists.newArrayList(false, false); for (SnapshotWindow snapshot : snapshots) { columnLabels.add(snapshot.getName().equals("default") ? "Current Window" : snapshot.getName()); columnKeys.add("devicePassingPercent_" + snapshot.getId().toString()); useConditionalStyles.add(true); } if (ExportType.csv.equals(type)) { columnLabels.add(0, "Parent Organization"); columnKeys.add(0, "parentOrgName"); if (currentOrg.getOrgTypeName().equals("District")) { columnLabels.add(1, "School Classification"); columnKeys.add(1, "schoolType"); } } switch (ExportType.valueOf(fileType)) { case csv: { ReportExportCsv csv = new ReportExportCsv(); csv.setColumnLabels(columnLabels); csv.setColumnKeys(columnKeys); csv.setData(reportItemProvider.export(type)); return csv; } case pdf: { ReportExportPdf pdf = new ReportExportPdf.Builder(columnLabels, columnKeys, useConditionalStyles, reportItemProvider.export(type)) .title("Progress Report - Device Indicators") .subtitle( (currentOrg.getOrgTypeName().equals("Readiness") ? "" : currentOrg.getName() + " - ") + "% Devices Meet the " + getRequirements() + " Requirements") .consortium(consortium.toString()).aggregationMessage(getAsOfDate() + " - Reports are updated hourly") .build(); pdf.setLegendTitle(getLegendTitle()); if (currentOrg.getOrgTypeName().equals("Readiness")) { pdf.setTemplate("reports/wrapper-progress-map.jrxml"); pdf.setMapUrl(geoChart.getUrl()); } else { pdf.setTemplate("reports/wrapper-progress.jrxml"); } return pdf; } } return null; } @Override protected ReportExport getAllSchoolsReportExport(ExportType type) throws Exception { return null; } public String getOrgCode() { return orgCode; } public void setOrgCode(String selectedOrgCode) { orgCode = selectedOrgCode; } public GeoChartBean getGeoChart() { return geoChart; } public void setGeoChart(GeoChartBean geoChart) { this.geoChart = geoChart; } public ReportItemProvider getReportItemProvider() { return reportItemProvider; } public DataGridState<?> getReportGrid() { return reportGrid; } public void setReportGrid(DataGridState<?> reportGrid) { this.reportGrid = reportGrid; } public String getStateCode() { return stateCode; } public void setStateCode(String stateCode) { this.stateCode = stateCode; } public boolean isDualConsortium() { return dualConsortium; } public String getStateName() { return stateName; } public void setStateName(String stateName) { this.stateName = stateName; } public String getLegendTitle() { return "Meeting Requirements"; } public Collection<SnapshotWindow> getSnapshots() { return snapshots; } public Org getCurrentOrg() { return currentOrg; } public String getCurrentOrgName() { StringBuilder sb = new StringBuilder(); if (currentOrg == null) { return ""; } if (!"".equals(currentOrg.getName())) { sb.append(currentOrg.getName()); } if (!"".equals(currentOrg.getLocalCode())) { if (sb.length() > 0) { sb.append(" (").append(currentOrg.getLocalCode()).append(")"); } else { sb.append(currentOrg.getLocalCode()); } } return sb.toString(); } }