diff --git a/WNPRC_Compliance/resources/queries/wnprc_compliance/MostRecentAccessReportSummary.sql b/WNPRC_Compliance/resources/queries/wnprc_compliance/MostRecentAccessReportSummary.sql index 4001496d6..01cfd832e 100644 --- a/WNPRC_Compliance/resources/queries/wnprc_compliance/MostRecentAccessReportSummary.sql +++ b/WNPRC_Compliance/resources/queries/wnprc_compliance/MostRecentAccessReportSummary.sql @@ -1,70 +1,22 @@ SELECT -ar.date as report_date, - -card_info.card_id, -cards.exempt, -cards.exempt_reason, -personsList.lastTbClearance, -personsList.measles_required, -personsList.isArchived, - -card_info.first_name, -card_info.last_name, -card_info.middle_name, - -access_info.access_levels, - -persons_to_cards.personid - -FROM ( - SELECT - report_id, - card_id, - GROUP_CONCAT(access_level, ';') as access_levels - - - FROM ( - SELECT - reports.report_id, - report_data.card_id, - report_data.access_level, - - - FROM wnprc_compliance.access_reports reports, wnprc_compliance.access_report_data report_data - WHERE ( - reports.date = (SELECT MAX(date) FROM wnprc_compliance.access_reports) - AND ( - report_data.report_id = reports.report_id - ) - ) - ) - - GROUP BY report_id, card_id -) as access_info - -LEFT JOIN wnprc_compliance.card_info card_info -on ( - access_info.card_id = card_info.card_id - AND - access_info.report_id = card_info.report_id -) - -LEFT JOIN wnprc_compliance.cards cards -ON ( - cards.card_id = access_info.card_id -) - -LEFT JOIN wnprc_compliance.persons_to_cards persons_to_cards -ON ( - persons_to_cards.cardid = access_info.card_id -) - -LEFT JOIN wnprc_compliance.personsList personsList -ON ( - personsList.personid = persons_to_cards.personid -) - -LEFT JOIN wnprc_compliance.access_reports ar -ON ( - ar.report_id = access_info.report_id -) \ No newline at end of file + ar.date as report_date, + card_info.card_id, + cards.exempt, + cards.exempt_reason, + personsList.lastTbClearance, + personsList.measles_required, + personsList.isArchived, + card_info.first_name, + card_info.last_name, + card_info.middle_name, + persons_to_cards.personid +FROM wnprc_compliance.access_reports ar + INNER JOIN wnprc_compliance.card_info card_info + ON ar.report_id = card_info.report_id + LEFT JOIN wnprc_compliance.cards cards + ON cards.card_id = card_info.card_id + LEFT JOIN wnprc_compliance.persons_to_cards persons_to_cards + ON persons_to_cards.cardid = card_info.card_id + LEFT JOIN wnprc_compliance.personsList personsList + ON personsList.personid = persons_to_cards.personid +WHERE ar.date = (SELECT MAX(date) FROM wnprc_compliance.access_reports) diff --git a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportRowParser.java b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportRowParser.java index 6dff03474..d6716065d 100644 --- a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportRowParser.java +++ b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportRowParser.java @@ -25,14 +25,13 @@ */ public class AccessReportRowParser { enum ColumnName { - FIRST_NAME (false, "Name (Last, First, Middle)"), - LAST_NAME (false, "Name (Last, First, Middle)"), - MIDDLE_NAME (false, "Name (Last, First, Middle)"), - CARD_NUMBER (true, "Badge ID(Issue)"), - CARD_ISSUED (false, "Badge Active"), - CARD_EXPIRE (false, "Badge Deactive"), + FIRST_NAME (false, "First Name"), + LAST_NAME (false, "Last Name"), + MIDDLE_NAME (false, "Middle Name"), + CARD_NUMBER (true, "Badge ID"), + CARD_ISSUED (false, "Badge Activate"), + CARD_EXPIRE (false, "Badge Deactivate"), BADGE_TYPE (false, "Badge Type"), - CARD_ISSUE_CODE (false, "Badge Id(Issue)"), ; boolean required; @@ -87,7 +86,7 @@ public AccessReportRowParser(Row headerRow) throws MalformedReportException { } } - public Pair parseRow(String reportId, Row row, Container container) throws ParseException + public CardInfo parseRow(Row row) throws ParseException { Map values = new HashMap<>(); @@ -96,23 +95,16 @@ public Pair parseRow(String reportId, Row row, Container c for (ColumnName columnName : cellIndexLookup.keySet()) { Cell cell = row.getCell(cellIndexLookup.get(columnName)); if (cell != null ) { - if (columnName.headerText.equals(ColumnName.FIRST_NAME.headerText)) - { - if (cell.getCellType() == CellType.STRING && !cell.getStringCellValue().isEmpty()) - { - Matcher matcher = Pattern.compile("^(.*?),\\s+(\\w+)(?:\\s+(\\w+))?$").matcher(cell.getStringCellValue()); - - if (matcher.find()) - { - values.put(ColumnName.FIRST_NAME, matcher.group(2)); - values.put(ColumnName.LAST_NAME, matcher.group(1)); - values.put(ColumnName.MIDDLE_NAME, matcher.group(3)); - } - } - + if(columnName == ColumnName.FIRST_NAME){ + values.put(ColumnName.FIRST_NAME, cell.getStringCellValue()); } - - if (columnName.headerText.equals(ColumnName.CARD_ISSUED.headerText)) + else if (columnName == ColumnName.MIDDLE_NAME){ + values.put(ColumnName.MIDDLE_NAME, cell.getStringCellValue()); + }else if (columnName == ColumnName.LAST_NAME){ + values.put(ColumnName.LAST_NAME, cell.getStringCellValue()); + }else if (columnName == ColumnName.BADGE_TYPE){ + values.put(ColumnName.BADGE_TYPE, cell.getStringCellValue()); + }else if (columnName == ColumnName.CARD_ISSUED) { if (!cell.toString().isEmpty()) { @@ -121,8 +113,7 @@ public Pair parseRow(String reportId, Row row, Container c values.put(ColumnName.CARD_ISSUED, d); } - } - if (columnName.headerText.equals(ColumnName.CARD_EXPIRE.headerText)) + }else if (columnName == ColumnName.CARD_EXPIRE) { if (!cell.toString().isEmpty()) { @@ -130,21 +121,12 @@ public Pair parseRow(String reportId, Row row, Container c Date d = df.parse(cell.toString()); values.put(ColumnName.CARD_EXPIRE, d); } + }else if (columnName == ColumnName.CARD_NUMBER) + { + values.put(ColumnName.CARD_NUMBER, cell.getStringCellValue()); } - if (columnName.headerText.equals(ColumnName.CARD_NUMBER.headerText)) - { - if (cell.getCellType() == CellType.STRING && !cell.getStringCellValue().isEmpty()) - { - Matcher matcher = Pattern.compile("(\\d+)\\s*\\((\\d+)\\)").matcher(cell.getStringCellValue()); - if (matcher.find()) - { - values.put(ColumnName.CARD_NUMBER, matcher.group(1)); - values.put(ColumnName.CARD_ISSUE_CODE, matcher.group(2)); - } - } - } String value = ""; if (cell.getCellType() == CellType.STRING) { @@ -152,11 +134,11 @@ public Pair parseRow(String reportId, Row row, Container c } if (!values.containsKey(columnName)) values.put(columnName, value); + } } - Pair pair = new Pair<>(new CardInfo(values), new AccessInfo(values)); - return pair; + return new CardInfo(values); } public static class CardInfo { @@ -187,9 +169,6 @@ public Date getCardIssued() { public Date getCardExpire() { return (Date) this.values.get(ColumnName.CARD_EXPIRE); } - public String getIssueCode() { - return (String) this.values.get(ColumnName.CARD_ISSUE_CODE); - } public String getCardType() { return (String) this.values.get(ColumnName.BADGE_TYPE); } @@ -200,15 +179,6 @@ public Map getValues() { } - public static class AccessInfo { - private Map values; - - public AccessInfo(Map values) { - this.values = values; - } - - } - public static class MalformedReportException extends Exception { public MalformedReportException(String message) { super(message); @@ -216,8 +186,9 @@ public MalformedReportException(String message) { } public static Date parseDate(String dateString) { - SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ssa"); + SimpleDateFormat dateFormat = new SimpleDateFormat("MM.dd.yy"); SimpleDateFormat shortDateFormat = new SimpleDateFormat("MM/dd/yyyy"); + SimpleDateFormat fullDateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ssa"); Date date; @@ -229,7 +200,12 @@ public static Date parseDate(String dateString) { date = shortDateFormat.parse(dateString); } catch(ParseException e2) { - throw new ApiUsageException("Unrecognized Date format: " + dateString); + try { + date = fullDateFormat.parse(dateString); + } + catch(ParseException e3) { + throw new ApiUsageException("Unrecognized Date format: " + dateString); + } } } diff --git a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportService.java b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportService.java index 576ba1a7c..eec0b49f6 100644 --- a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportService.java +++ b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportService.java @@ -54,19 +54,25 @@ public AccessReportService(User user, Container container) { this.container = container; } - public void importReport(InputStream stream) throws IOException, AccessReportRowParser.MalformedReportException, ParseException + public void importReport(InputStream stream, String filename) throws IOException, AccessReportRowParser.MalformedReportException, ParseException { String reportid = UUID.randomUUID().toString().toUpperCase(); Sheet sheet = new ExcelLoader(stream,false, null).getSheet(); - Row titleRow = sheet.getRow(1); - if (!titleRow.getCell(0).getStringCellValue().equalsIgnoreCase("Access Level Assignments to Cardholders")) { + // Ensure all necessary columns are present in an uploaded report + Row columnHeaderRow = sheet.getRow(0); + if(!columnHeaderRow.getCell(3).getStringCellValue().equalsIgnoreCase("Last Name") + || !columnHeaderRow.getCell(5).getStringCellValue().equalsIgnoreCase("First Name") + || !columnHeaderRow.getCell(7).getStringCellValue().equalsIgnoreCase("Middle Name") + || !columnHeaderRow.getCell(23).getStringCellValue().equalsIgnoreCase("Badge Type") + || !columnHeaderRow.getCell(25).getStringCellValue().equalsIgnoreCase("Badge ID") + || !columnHeaderRow.getCell(30).getStringCellValue().equalsIgnoreCase("Badge Activate") + || !columnHeaderRow.getCell(32).getStringCellValue().equalsIgnoreCase("Badge Deactivate")){ throw new ApiUsageException("You can only upload area rights reports here."); } - Row dateRow = sheet.getRow(6); - //the report created date is the 13th column over - Matcher matcher = Pattern.compile("Report\\s+Date:\\s*(\\d{2}/\\d{2}/\\d{4}\\s+\\d{1,2}:\\d{2}:\\d{2}[AP]M)").matcher(dateRow.getCell(14).getStringCellValue()); + //the report created is in the file name + Matcher matcher = Pattern.compile("(\\d{1,2}\\.\\d{1,2}\\.\\d{2})").matcher(filename); String reportDateTime; Date generatedOn; if (matcher.find()) @@ -88,73 +94,20 @@ public void importReport(InputStream stream) throws IOException, AccessReportRow } Map cardInfos = new HashMap<>(); - List> accessData = new ArrayList<>(); - - - //if the cell contains Prim and Barrier - Pattern accessLevelPattern = Pattern.compile("Access Level:\\s*"); - Iterator rows = sheet.rowIterator(); - AccessReportRowParser rowParser = null; - String accessLevel = ""; - outer: + AccessReportRowParser rowParser = new AccessReportRowParser(columnHeaderRow); while (rows.hasNext()) { Row currentRow = rows.next(); - //don't parse items until we reach the main block - if (currentRow.getRowNum() < 8) - { - continue; - } - if (currentRow.getCell(4) == null) - { + // Skip header row + if(currentRow.getRowNum() == 0){ continue; } - String firstCellText = currentRow.getCell(0).getStringCellValue(); - - Matcher accessLevelMatcher = accessLevelPattern.matcher(firstCellText); - //we've encountered an access level block of text - //we can grab the header and skip a row - if (accessLevelMatcher.matches()) - { - accessLevel = currentRow.getCell(4).getStringCellValue(); - - // We are about to go into a block of values. First, eat the blank line - rows.next(); - - // Now eat the header line - Row headerRow = rows.next(); - //sets up the column names from the header row? - - // - rowParser = new AccessReportRowParser(headerRow); - currentRow = rows.next(); - } - if (rowParser == null) - { - continue; - } - Pair results = rowParser.parseRow(reportid, currentRow, container); - AccessReportRowParser.CardInfo cardInfo = results.first; - AccessReportRowParser.AccessInfo accessInfo = results.second; + AccessReportRowParser.CardInfo cardInfo = rowParser.parseRow(currentRow); if (cardInfo.getValues().isEmpty()) continue; - - //end of spreadsheet pattern - Pattern endOfSheetPattern = Pattern.compile("Total Badges Required for Download:"); - if (endOfSheetPattern.matcher(cardInfo.getFirstName()).matches()) - { - int getNumCards = (int) currentRow.getCell(10).getNumericCellValue(); - if (cardInfos.size() != getNumCards) - { - throw new RuntimeException("Card number does not equal total badge count in sheet, upload failed."); - } - break; - } - - String cardNumber = cardInfo.getCardNumber(); if (cardNumber == null || cardNumber.equals("")) { @@ -171,19 +124,10 @@ public void importReport(InputStream stream) throws IOException, AccessReportRow cardInfoJSON.put("middle_name", cardInfo.getMiddleName()); cardInfoJSON.put("date_issued", cardInfo.getCardIssued()); cardInfoJSON.put("date_expire", cardInfo.getCardExpire()); - cardInfoJSON.put("issue_code", cardInfo.getIssueCode()); cardInfoJSON.put("card_type", cardInfo.getCardType()); cardInfoJSON.put("container", container.getId()); cardInfos.put(cardNumber, cardInfoJSON); - - JSONObject accessInfoJSON = new JSONObject(); - accessInfoJSON.put("report_id", reportid); - accessInfoJSON.put("access_level", accessLevel); - accessInfoJSON.put("card_id", cardNumber); - accessInfoJSON.put("container", container.getId()); - - accessData.add(accessInfoJSON.toMap()); } try (DbScope.Transaction transaction = DbSchema.get(WNPRC_ComplianceSchema.NAME, DbSchemaType.Module).getScope().ensureTransaction()) { @@ -204,9 +148,6 @@ public void importReport(InputStream stream) throws IOException, AccessReportRow } cardsUpdater.upsert(cardsList); - SimpleQueryUpdater dataUpdater = new SimpleQueryUpdater(user, container, WNPRC_ComplianceSchema.NAME, "access_report_data"); - dataUpdater.upsert(accessData); - List> cardInfoList = new ArrayList<>(cardInfos.values().stream().map(JSONObject::toMap).toList()); SimpleQueryUpdater cardInfoUpdater = new SimpleQueryUpdater(user, container, WNPRC_ComplianceSchema.NAME, "card_info"); cardInfoUpdater.upsert(cardInfoList); diff --git a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/WNPRC_ComplianceController.java b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/WNPRC_ComplianceController.java index c79cef957..0affad69f 100644 --- a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/WNPRC_ComplianceController.java +++ b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/WNPRC_ComplianceController.java @@ -292,7 +292,7 @@ protected File handleFile(String filename, InputStream input, Writer writer) thr try { AccessReportService service = new AccessReportService(getUser(), getContainer()); - service.importReport(input); + service.importReport(input, filename); writer.write("Handled file: " + filename); } catch (Throwable e) {