package net.techreadiness.plugin.action.task.dataentry; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import javax.inject.Inject; import net.techreadiness.annotation.CoreSecured; import net.techreadiness.plugin.service.SnapshotWindowService; import net.techreadiness.plugin.service.object.SnapshotOrg; import net.techreadiness.plugin.service.object.SnapshotWindow; import net.techreadiness.plugin.service.reports.MinimumRecommendedFlag; import net.techreadiness.plugin.service.reports.ReportsService; import net.techreadiness.security.CorePermissionCodes; import net.techreadiness.service.DeviceService; import net.techreadiness.service.object.Device; import net.techreadiness.service.object.Org; import net.techreadiness.ui.action.task.org.dataentry.DataEntryTaskFlowAction; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.opensymphony.xwork2.Preparable; import com.opensymphony.xwork2.util.Element; import com.opensymphony.xwork2.util.Key; @Results({ @Result(name = "success", location = "/net/techreadiness/plugin/action/org/dataentry/dataEntry.jsp"), @Result(name = "noorg", location = "/net/techreadiness/plugin/action/org/dataentry/noorg.jsp") }) public class DataEntryAction extends DataEntryTaskFlowAction implements Preparable { private static final long serialVersionUID = 1L; private Multimap<Long, String> dataEntryErrors; private Multimap<Long, String> abnormalMessages; private SnapshotWindow snapshot; @Key(Long.class) @Element(Boolean.class) private Map<Long, Boolean> dataEntryComplete; @Inject private SnapshotWindowService snapshotService; @Inject private DeviceService deviceService; @Inject private ReportsService reportsService; @CoreSecured({ CorePermissionCodes.READY_CUSTOMER_NETWORK_INFRASTRUCTURE }) @Override public String execute() { snapshot = snapshotService.getByScopeIdAndName(getServiceContext(), getServiceContext().getScopeId(), ReportsService.DEFAULT_SNAPSHOT_WINDOW); for (Org org : getTaskFlowData().getOrgs()) { if (StringUtils.isBlank(org.getInternetSpeed())) { dataEntryErrors.put(org.getOrgId(), "Estimated Internet Bandwidth"); } if (StringUtils.isBlank(org.getInternetUtilization())) { dataEntryErrors.put(org.getOrgId(), "Estimated Internet Bandwidth Utilization"); } else { int internetBandwidth = Integer.parseInt(org.getInternetUtilization()); if (internetBandwidth >= 90) { abnormalMessages.put(org.getOrgId(), "Internet Bandwidth utilization is greater than or equal to 90%"); } else { if (internetBandwidth <= 5) { abnormalMessages.put(org.getOrgId(), "Internet Bandwidth utilization is less than or equal to 5%"); } } } if (StringUtils.isBlank(org.getNetworkSpeed())) { dataEntryErrors.put(org.getOrgId(), "Estimated Internal Network Bandwidth"); } if (StringUtils.isBlank(org.getNetworkUtilization())) { dataEntryErrors.put(org.getOrgId(), "Estimated Internal Network Bandwidth Utilization"); } else { int networkBandwidth = Integer.parseInt(org.getNetworkUtilization()); if (networkBandwidth >= 90) { abnormalMessages.put(org.getOrgId(), "Internal Network Bandwidth utilization is greater than or equal to 90%"); } else { if (networkBandwidth <= 5) { abnormalMessages.put(org.getOrgId(), "Internal Network Bandwidth utilization is less than or equal to 5%"); } } } if (StringUtils.isBlank(org.getTestingWindowLength())) { dataEntryErrors.put(org.getOrgId(), "Length of Testing Window in School Days"); } if (StringUtils.isBlank(org.getSessionsPerDay())) { dataEntryErrors.put(org.getOrgId(), "SessionsPerDay"); } else { int sessionsPerDay = Integer.parseInt(org.getSessionsPerDay()); if (sessionsPerDay > 4) { abnormalMessages.put(org.getOrgId(), "School has 5 or more sessions per day"); } } int enrollmentCountTotal = getAnsweredEnrollmentCount(org); if (enrollmentCountTotal == 0) { dataEntryErrors.put(org.getOrgId(), "At least one grade must have a non-zero enrollment count"); } Collection<Device> devices = deviceService.findByOrgId(getServiceContext(), org.getOrgId()); if (devices.size() == 0) { abnormalMessages.put(org.getOrgId(), "School has not provided device data"); } for (Device device : devices) { if (device.getOperatingSystem() == null) { dataEntryErrors.put(org.getOrgId(), "Operating System is required"); } if (device.getMemory() == null) { dataEntryErrors.put(org.getOrgId(), "Memory is required"); } if (device.getScreenResolution() == null) { dataEntryErrors.put(org.getOrgId(), "Screen Resolution is required"); } if (device.getMonitorDisplaySize() == null) { dataEntryErrors.put(org.getOrgId(), "Monitor / Display Size is required"); } if (device.getEnvironment() == null) { dataEntryErrors.put(org.getOrgId(), "Assessment Environment is required"); } } SnapshotOrg snapshotOrg = reportsService.getSnapshotDataForOrg(snapshot.getSnapshotWindowId(), org.getOrgId(), MinimumRecommendedFlag.MINIMUM); if (snapshotOrg != null) { String studentCount = snapshotOrg.getTestingStudentCount(); String totalDeviceCount = snapshotOrg.getDeviceCount(); if (studentCount != null && !(studentCount.equals("(missing)") && totalDeviceCount != null && !totalDeviceCount .equals("(missing)"))) { int testStudentCountDoubled = NumberUtils.toInt(studentCount) * 2; if (NumberUtils.toInt(totalDeviceCount) > testStudentCountDoubled) { abnormalMessages.put(org.getOrgId(), "Device-to-test-taker ratio is greater than 2:1"); } } } StringBuilder sbd = new StringBuilder(); sbd.append("High grade level enrollment in the following grades:"); Collection<String> highEnrollment = new HashSet<>(); if (hasHighEnrollment(org.getEnrollmentCountK(), snapshot.getCalcEnrollmentCountKMedian(), snapshot.getCalcEnrollmentCountKStddev())) { highEnrollment.add("K"); } if (hasHighEnrollment(org.getEnrollmentCount1(), snapshot.getCalcEnrollmentCount1Median(), snapshot.getCalcEnrollmentCount1Stddev())) { highEnrollment.add("1"); } if (hasHighEnrollment(org.getEnrollmentCount2(), snapshot.getCalcEnrollmentCount2Median(), snapshot.getCalcEnrollmentCount2Stddev())) { highEnrollment.add("2"); } if (hasHighEnrollment(org.getEnrollmentCount3(), snapshot.getCalcEnrollmentCount3Median(), snapshot.getCalcEnrollmentCount3Stddev())) { highEnrollment.add("3"); } if (hasHighEnrollment(org.getEnrollmentCount4(), snapshot.getCalcEnrollmentCount4Median(), snapshot.getCalcEnrollmentCount4Stddev())) { highEnrollment.add("4"); } if (hasHighEnrollment(org.getEnrollmentCount5(), snapshot.getCalcEnrollmentCount5Median(), snapshot.getCalcEnrollmentCount5Stddev())) { highEnrollment.add("5"); } if (hasHighEnrollment(org.getEnrollmentCount6(), snapshot.getCalcEnrollmentCount6Median(), snapshot.getCalcEnrollmentCount6Stddev())) { highEnrollment.add("6"); } if (hasHighEnrollment(org.getEnrollmentCount7(), snapshot.getCalcEnrollmentCount7Median(), snapshot.getCalcEnrollmentCount7Stddev())) { highEnrollment.add("7"); } if (hasHighEnrollment(org.getEnrollmentCount8(), snapshot.getCalcEnrollmentCount8Median(), snapshot.getCalcEnrollmentCount8Stddev())) { highEnrollment.add("8"); } if (hasHighEnrollment(org.getEnrollmentCount9(), snapshot.getCalcEnrollmentCount9Median(), snapshot.getCalcEnrollmentCount9Stddev())) { highEnrollment.add("9"); } if (hasHighEnrollment(org.getEnrollmentCount10(), snapshot.getCalcEnrollmentCount10Median(), snapshot.getCalcEnrollmentCount10Stddev())) { highEnrollment.add("10"); } if (hasHighEnrollment(org.getEnrollmentCount11(), snapshot.getCalcEnrollmentCount11Median(), snapshot.getCalcEnrollmentCount11Stddev())) { highEnrollment.add("11"); } if (hasHighEnrollment(org.getEnrollmentCount12(), snapshot.getCalcEnrollmentCount12Median(), snapshot.getCalcEnrollmentCount12Stddev())) { highEnrollment.add("12"); } if (!highEnrollment.isEmpty()) { for (String grade : highEnrollment) { sbd.append(" "); sbd.append(grade); } abnormalMessages.put(org.getOrgId(), sbd.toString()); } } return SUCCESS; } private static boolean hasHighEnrollment(String enrollment, Integer median, Double stdDev) { if (enrollment != null && !"(missing)".equals(enrollment) && median != null && stdDev != null) { int count = NumberUtils.toInt(enrollment); if (count > median.intValue() + stdDev.doubleValue() * 4) { return true; } } return false; } private static int getAnsweredEnrollmentCount(Org org) { int count = (StringUtils.isBlank(org.getEnrollmentCountK()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount1()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount2()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount3()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount4()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount5()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount6()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount7()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount8()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount9()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount10()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount11()) ? 0 : 1) + (StringUtils.isBlank(org.getEnrollmentCount12()) ? 0 : 1); return count; } @Override public void prepare() throws Exception { dataEntryErrors = HashMultimap.create(); abnormalMessages = HashMultimap.create(); dataEntryComplete = new HashMap<>(); } public Multimap<Long, String> getDataEntryErrors() { return dataEntryErrors; } public Multimap<Long, String> getAbnormalMessages() { return abnormalMessages; } public Map<Long, Boolean> getDataEntryComplete() { return dataEntryComplete; } }