package net.techreadiness.plugin.action.reports.staff; import java.awt.Color; import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import net.techreadiness.annotation.CoreSecured; 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.reports.ReportPdfHighlightCondition; 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.beanutils.BeanUtils; 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 ar.com.fdvs.dj.domain.Style; import ar.com.fdvs.dj.domain.entities.conditionalStyle.ConditionalStyle; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; public class StaffReportAction extends ReportAction { private static final long serialVersionUID = 1L; private String orgCode; private String stateCode; private String stateName; private GeoChartBean geoChart; private String question; private Map<String, String> questions; private Org currentOrg; private boolean dualConsortium; private String reportAggDate; @Inject private ReportsService reportService; @Inject @Qualifier("StaffReportItemProvider") private ReportItemProvider reportItemProvider; @ConversationScoped(value = "staffDataGridState") private DataGridState<?> reportGrid; @CoreSecured({ CorePermissionCodes.READY_CUSTOMER_STAFF_PERSONNEL_RPT }) @Action(value = "staffReport", results = { @Result(name = "map", location = "/net/techreadiness/plugin/action/reports/staff/map.jsp"), @Result(name = "table", location = "/net/techreadiness/plugin/action/reports/staff/table.jsp"), @Result(name = "org", location = "/net/techreadiness/plugin/action/reports/staff/org.jsp") }) public String staffReport() throws Exception { getData(); buildBreadcrumbs(currentOrg, consortium, "staffReport"); return getReturn(); } private void getData() throws Exception { ServiceContext context = getServiceContext(); // query list of questions; if (questions == null) { questions = new LinkedHashMap<>(); questions.put("admin_count", "Having a sufficient number of test administrators to support online testing."); questions.put("admin_understanding", "Test administrators having sufficient technical understanding to support online testing."); questions.put("admin_training", "Providing all appropriate training needed for test administrators."); questions.put("techstaff_count", "Having a sufficient number of technology support staff to support online testing."); questions.put("techstaff_understanding", "Technology support staff having sufficient technical understanding to support online testing."); questions.put("techstaff_training", "Providing all appropriate training needed for technology support staff."); } if (question == null && questions != null && !questions.isEmpty()) { question = questions.keySet().iterator().next(); } // 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("prevOrgStaff") == null || !currentOrg.getId().equals(session.get("prevOrgStaff"))) { reportGrid.setPage(1); } session.put("prevOrgStaff", 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); reportItemProvider.setSnapshotWindow(getCurrentSnapshotWindow()); reportItemProvider.setOrg(currentOrg); reportItemProvider.setMinimumRecommendedFlag(getMinimumRecommendedFlag()); reportItemProvider.setQuestion(question); if (currentOrg.getOrgTypeName().equals("Readiness")) { // query the map data Collection<Map<String, String>> states = reportService.retrieveSurveySummaryForChildOrgs( getCurrentSnapshotWindow().getSnapshotWindowId(), currentOrg.getOrgId(), question, true, 0, 0).getRows(); // put state data into geochart geoChart = new GeoChartBean(); geoChart.setHoverLabel("Aggregated Average Level of Concern (Scale 0 -10, zero is no concern)"); if (viewBy != null && viewBy.equals(ViewBy.table)) { geoChart.setWidth(285); geoChart.setHeight(175); } if (states != null) { for (Map<String, String> data : states) { reportAggDate = data.get("createDate"); geoChart.addSurveyData(data.get("orgCode"), StringUtils.remove(data.get("orgName"), "(" + data.get("localOrgCode") + ")"), data.get("localOrgCode"), data.get("levelOfConcernAverageResponse")); } } } else if (currentOrg.getOrgTypeName().equals("State")) { // set state code and name (needed for image on page) stateCode = currentOrg.getLocalCode().toUpperCase(); stateName = currentOrg.getName(); // query for aggDate Collection<Map<String, String>> districts = reportService.retrieveSurveySummaryForChildOrgs( getCurrentSnapshotWindow().getSnapshotWindowId(), currentOrg.getOrgId(), question, true, 0, 0).getRows(); if (districts != null && !districts.isEmpty()) { reportAggDate = Iterables.getFirst(districts, null).get("createDate"); } } 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(); // query for aggDate Collection<Map<String, String>> schools = reportService.retrieveSurveySummaryForChildOrgs( getCurrentSnapshotWindow().getSnapshotWindowId(), currentOrg.getOrgId(), question, true, 0, 0).getRows(); if (schools != null && !schools.isEmpty()) { reportAggDate = Iterables.getFirst(schools, null).get("createDate"); } } else if (currentOrg.getOrgTypeName().equals("School")) { Org state = orgService.getParentOrgOfType(getServiceContext(), currentOrg.getOrgId(), "state"); // set state code and name (needed for image on page) stateCode = state.getLocalCode().toUpperCase(); stateName = state.getName(); // query for aggDate Collection<Map<String, String>> result = reportService.retrieveSurveySummaryForOrg( getCurrentSnapshotWindow().getSnapshotWindowId(), currentOrg.getOrgId(), question).getRows(); Map<String, String> school = Iterables.getFirst(result, new HashMap<String, String>()); if (school != null && !school.isEmpty()) { reportAggDate = school.get("createDate"); } } } @Override protected ReportExport getReportExport(ExportType type) throws Exception { // populate reportItemProvider setFileName("StaffReport"); getData(); List<String> columnLabels, columnKeys; columnLabels = Lists.newArrayList("Parent Organization", "Organization", "Org Code", "Level of Concern 0-3", "Level of Concern 4-5", "Level of Concern 6-7", "Level of Concern 8-10", "Aggregated Average Response"); columnKeys = Lists.newArrayList("parentOrgName", "orgName", "orgCode", "levelOfConcernCount0to3", "levelOfConcernCount4to5", "levelOfConcernCount6to7", "levelOfConcernCount8to10", "levelOfConcernAverageResponse"); // remove last column if its a school and replace with Other if (currentOrg.getOrgTypeName().equals("School")) { columnLabels.set(columnLabels.size() - 1, "Other"); columnKeys.set(columnKeys.size() - 1, "levelOfConcernOther"); } if (currentOrg.getOrgTypeName().equals("District") || currentOrg.getOrgTypeName().equals("School")) { columnLabels = Lists .newArrayList("Parent Organization", "Organization", "Org Code", "Completion Status", "Level of Concern 0-3", "Level of Concern 4-5", "Level of Concern 6-7", "Level of Concern 8-10", "Other"); columnKeys = Lists.newArrayList("parentOrgName", "orgName", "orgCode", "dataEntryComplete", "levelOfConcernCount0to3", "levelOfConcernCount4to5", "levelOfConcernCount6to7", "levelOfConcernCount8to10", "levelOfConcernOther"); } if (ExportType.csv.equals(type) && 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, reportItemProvider.export(type)) .title("Staff & Personnel Indicator Report") .subtitle(questions.get(question)) .consortium(consortium.toString()) .aggregationMessage( reportAggDate == null ? "" : "Data as of " + reportAggDate + " - Reports are updated hourly") .build(); pdf.setConditionalStyles(createConditionalStyles(pdf.getDetailStyle())); pdf.setSuppressConditionalStyles(currentOrg.getOrgTypeName().equals("District") || currentOrg.getOrgTypeName().equals("School")); pdf.setTemplate("reports/wrapper-survey.jrxml"); if (!getReturn().equals("org")) { pdf.setMapUrl(geoChart.getUrl()); pdf.setTemplate("reports/wrapper-survey-map.jrxml"); } return pdf; } } return null; } @Override protected ReportExport getAllSchoolsReportExport(ExportType type) throws Exception { return null; } private static List<ConditionalStyle> createConditionalStyles(Style baseStyle) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { Style reportLevel1 = (Style) BeanUtils.cloneBean(baseStyle); reportLevel1.setBackgroundColor(new Color(184, 31, 75)); reportLevel1.setTextColor(Color.white); reportLevel1.setTransparent(false); Style reportLevel2 = (Style) BeanUtils.cloneBean(baseStyle); reportLevel2.setBackgroundColor(new Color(246, 133, 31)); reportLevel2.setTransparent(false); Style reportLevel3 = (Style) BeanUtils.cloneBean(baseStyle); reportLevel3.setBackgroundColor(new Color(252, 185, 19)); reportLevel3.setTransparent(false); Style reportLevel4 = (Style) BeanUtils.cloneBean(baseStyle); reportLevel4.setBackgroundColor(new Color(0, 161, 94)); reportLevel4.setTransparent(false); ReportPdfHighlightCondition status1 = new ReportPdfHighlightCondition(0, 3.00); ReportPdfHighlightCondition status2 = new ReportPdfHighlightCondition(3.01, 5.00); ReportPdfHighlightCondition status3 = new ReportPdfHighlightCondition(5.01, 7.00); ReportPdfHighlightCondition status4 = new ReportPdfHighlightCondition(7.01, 10); List<ConditionalStyle> conditionalStyles = Lists.newArrayList(); conditionalStyles.add(new ConditionalStyle(status1, reportLevel4)); conditionalStyles.add(new ConditionalStyle(status2, reportLevel3)); conditionalStyles.add(new ConditionalStyle(status3, reportLevel2)); conditionalStyles.add(new ConditionalStyle(status4, reportLevel1)); return conditionalStyles; } public String getQuestion() { return question; } public void setQuestion(String question) { this.question = question; } public Map<String, String> getQuestions() { return questions; } 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; } private String getReturn() { return currentOrg != null && currentOrg.getOrgTypeName().equals("Readiness") ? getViewBy() : "org"; } 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 Org getCurrentOrg() { return currentOrg; } public String getReportAggDate() { return reportAggDate; } public String getLegendTitle() { return "Level of Concern"; } }