diff --git a/WNPRC_Compliance/module.properties b/WNPRC_Compliance/module.properties
index 97cb3c7ae..0c6656025 100644
--- a/WNPRC_Compliance/module.properties
+++ b/WNPRC_Compliance/module.properties
@@ -4,6 +4,6 @@ License: Apache 2.0
LicenseURL: http://www.apache.org/licenses/LICENSE-2.0
ModuleClass: org.labkey.wnprc_compliance.WNPRC_ComplianceModule
Name: WNPRC_Compliance
-SchemaVersion: 21.001
+SchemaVersion: 25.001
SupportedDatabases: pgsql
ManageVersion: false
diff --git a/WNPRC_Compliance/resources/queries/wnprc_compliance/MostRecentAccessReportSummary.sql b/WNPRC_Compliance/resources/queries/wnprc_compliance/MostRecentAccessReportSummary.sql
index 5fb8f372b..4001496d6 100644
--- a/WNPRC_Compliance/resources/queries/wnprc_compliance/MostRecentAccessReportSummary.sql
+++ b/WNPRC_Compliance/resources/queries/wnprc_compliance/MostRecentAccessReportSummary.sql
@@ -11,13 +11,8 @@ personsList.isArchived,
card_info.first_name,
card_info.last_name,
card_info.middle_name,
-card_info.department,
-card_info.employee_number,
-card_info.info2,
-card_info.info3,
-card_info.info5,
-access_info.areas,
+access_info.access_levels,
persons_to_cards.personid
@@ -25,19 +20,14 @@ FROM (
SELECT
report_id,
card_id,
- GROUP_CONCAT(display_area, ';') as areas
+ GROUP_CONCAT(access_level, ';') as access_levels
FROM (
SELECT
reports.report_id,
report_data.card_id,
- report_data.enabled,
- report_data.area,
- CASE
- WHEN report_data.enabled IS FALSE THEN CAST(COALESCE(report_data.area, '') || ' (disabled)' as VARCHAR)
- ELSE report_data.area
- END as display_area
+ report_data.access_level,
FROM wnprc_compliance.access_reports reports, wnprc_compliance.access_report_data report_data
diff --git a/WNPRC_Compliance/resources/queries/wnprc_compliance/personsList.sql b/WNPRC_Compliance/resources/queries/wnprc_compliance/personsList.sql
index c15b87e36..7f8fa893c 100644
--- a/WNPRC_Compliance/resources/queries/wnprc_compliance/personsList.sql
+++ b/WNPRC_Compliance/resources/queries/wnprc_compliance/personsList.sql
@@ -4,7 +4,6 @@ last_name,
first_name,
middle_name,
date_of_birth,
-cardInfo.employee_number,
notes,
tbResults.lastClearance as lastTbClearance,
measlesResults.lastClearance as measlesClearance,
@@ -51,16 +50,3 @@ LEFT JOIN (
ON measlesResults.person_id = persons.personid
---Adding employee_number from card_info table. Need to select the latest uploaded record to the card_info table
---Use person_to_cards table to link the personid to the card_id.
-LEFT JOIN wnprc_compliance.persons_to_cards pers_to_card ON (persons.personid = pers_to_card.personid)
-LEFT JOIN
- (
- SELECT card_info.employee_number, card_info.card_id, MAX(card_info.created)
- FROM wnprc_compliance.card_info
- GROUP BY card_info.card_id, card_info.employee_number
- ) cardInfo
-ON (pers_to_card.cardid = cardInfo.card_id)
-
-ORDER BY last_name ASC
-
diff --git a/WNPRC_Compliance/resources/queries/wnprc_compliance/searchResults.sql b/WNPRC_Compliance/resources/queries/wnprc_compliance/searchResults.sql
index ace514a3b..0f1a68bc4 100644
--- a/WNPRC_Compliance/resources/queries/wnprc_compliance/searchResults.sql
+++ b/WNPRC_Compliance/resources/queries/wnprc_compliance/searchResults.sql
@@ -7,9 +7,9 @@ id,
first_name,
middle_name,
last_name,
-display,
+COALESCE(display, '') as display,
LCASE(display) as displayLcase,
-notes,
+COALESCE(notes, '') as notes,
"type"
FROM (
@@ -33,7 +33,7 @@ FROM (
SELECT
card_id as id,
first_name,
- middle_name,
+ COALESCE(middle_name, ''),
last_name,
COALESCE(first_name, '') || ' ' || COALESCE(middle_name, '') || ' ' || COALESCE(last_name, '') || ' (' || card_id || ')' as display,
COALESCE(department || ';', '') || COALESCE(info2 || ';', '') || COALESCE(info3 || ';', '') as notes,
@@ -48,7 +48,7 @@ FROM (
SELECT
personid as id,
first_name,
- middle_name,
+ COALESCE(middle_name, ''),
last_name,
COALESCE(first_name, '') || ' ' || COALESCE(middle_name, '') || ' ' || COALESCE(last_name, '') as display,
notes,
diff --git a/WNPRC_Compliance/resources/queries/wnprc_compliance/unidentifiedCards.sql b/WNPRC_Compliance/resources/queries/wnprc_compliance/unidentifiedCards.sql
index 21bd8607a..a237bd342 100644
--- a/WNPRC_Compliance/resources/queries/wnprc_compliance/unidentifiedCards.sql
+++ b/WNPRC_Compliance/resources/queries/wnprc_compliance/unidentifiedCards.sql
@@ -3,11 +3,10 @@ cards.card_id,
last_name,
first_name,
middle_name,
-department,
-employee_number,
-info2,
-info3,
-info5
+card_info.card_type,
+to_char(card_info.date_issued , 'yyyy-MM-dd') AS date_issued,
+to_char(card_info.date_expire, 'yyyy-MM-dd') AS date_expire,
+card_info.issue_code
FROM (
SELECT
@@ -18,12 +17,16 @@ FROM (
SELECT
unknown_cards.card_id,
card_info.report_id,
- card_info.report_id.date
+ card_info.report_id.date,
+ card_info.card_type,
+ card_info.date_issued,
+ card_info.date_expire,
+ card_info.issue_code
FROM (
SELECT
cards.card_id,
- persons_to_cards.personid
+ persons_to_cards.personid,
FROM (
SELECT card_id
diff --git a/WNPRC_Compliance/resources/schemas/dbscripts/postgresql/wnprc_compliance-25.000-25.001.sql b/WNPRC_Compliance/resources/schemas/dbscripts/postgresql/wnprc_compliance-25.000-25.001.sql
new file mode 100644
index 000000000..3d91d1074
--- /dev/null
+++ b/WNPRC_Compliance/resources/schemas/dbscripts/postgresql/wnprc_compliance-25.000-25.001.sql
@@ -0,0 +1,23 @@
+ALTER TABLE wnprc_compliance.card_info ADD COLUMN IF NOT EXISTS card_type text;
+ALTER TABLE wnprc_compliance.card_info ADD COLUMN IF NOT EXISTS date_issued timestamp;
+ALTER TABLE wnprc_compliance.card_info ADD COLUMN IF NOT EXISTS date_expire timestamp;
+ALTER TABLE wnprc_compliance.card_info ADD COLUMN IF NOT EXISTS issue_code int;
+
+ALTER TABLE wnprc_compliance.access_report_data RENAME TO access_report_data_old;
+
+
+DROP TABLE IF EXISTS wnprc_compliance.access_report_data;
+CREATE TABLE wnprc_compliance.access_report_data (
+ report_id TEXT,
+ access_level TEXT,
+ card_id TEXT,
+
+ container entityid NOT NULL,
+ createdby userid,
+ created TIMESTAMP,
+ modifiedby userid,
+ modified TIMESTAMP,
+
+ CONSTRAINT PK_access_report_data_new PRIMARY KEY (report_id, access_level, card_id),
+ CONSTRAINT FK_access_report_data_access_reports_new FOREIGN KEY (report_id) REFERENCES wnprc_compliance.access_reports (report_id)
+);
diff --git a/WNPRC_Compliance/resources/schemas/wnprc_compliance.xml b/WNPRC_Compliance/resources/schemas/wnprc_compliance.xml
index 80be1b01e..250b6ace1 100644
--- a/WNPRC_Compliance/resources/schemas/wnprc_compliance.xml
+++ b/WNPRC_Compliance/resources/schemas/wnprc_compliance.xml
@@ -135,6 +135,18 @@
+
@@ -156,6 +168,10 @@
+
+
+
+
diff --git a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportRowParser.java b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportRowParser.java
index ddf333310..6dff03474 100644
--- a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportRowParser.java
+++ b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportRowParser.java
@@ -8,6 +8,7 @@
import org.labkey.api.data.Container;
import org.labkey.api.util.Pair;
+import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -16,6 +17,7 @@
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
@@ -23,20 +25,14 @@
*/
public class AccessReportRowParser {
enum ColumnName {
- FIRST_NAME (false, "FirstName"),
- LAST_NAME (false, "LastName"),
- MIDDLE_NAME (false, "MiddleName"),
- DEPARTMENT (false, "department"),
- EMPLOYEE_NUMBER (false, "empNumber"),
- CARD_NUMBER (true, "CardNumber"),
- STATE (false, "state"),
- TIME_ENTERED (false, "timeEntered", Date.class),
- INFO2 (false, "info2"),
- INFO3 (false, "info3"),
- INFO5 (false, "info5"),
- // This column only appears some times, but it appears to be the access schedule for the employee (what
- // hours they're allowed to use the door).
- SCHEDULE_PT (false, "scheuld_pt")
+ 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"),
+ BADGE_TYPE (false, "Badge Type"),
+ CARD_ISSUE_CODE (false, "Badge Id(Issue)"),
;
boolean required;
@@ -91,46 +87,75 @@ public AccessReportRowParser(Row headerRow) throws MalformedReportException {
}
}
- public Pair parseRow(String reportId, Row row, Container container) {
+ public Pair parseRow(String reportId, Row row, Container container) throws ParseException
+ {
Map values = new HashMap<>();
+
+ //TODO maybe just grab the names directly instead of this loop
for (ColumnName columnName : cellIndexLookup.keySet()) {
Cell cell = row.getCell(cellIndexLookup.get(columnName));
-
- if (cell != null) {
- if (columnName.type == Date.class) {
- Date value;
- if (cell.getCellType() == CellType.STRING) {
- value = parseDate(cell.getStringCellValue());
+ 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));
+ }
}
- else if (cell.getCellType() == CellType.NUMERIC) {
- value = cell.getDateCellValue();
+
+ }
+
+ if (columnName.headerText.equals(ColumnName.CARD_ISSUED.headerText))
+ {
+ if (!cell.toString().isEmpty())
+ {
+ DateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
+ Date d = df.parse(cell.toString());
+ values.put(ColumnName.CARD_ISSUED, d);
+
}
- else if (cell.getCellType() == CellType.BLANK) {
- value = null;
+ }
+ if (columnName.headerText.equals(ColumnName.CARD_EXPIRE.headerText))
+ {
+ if (!cell.toString().isEmpty())
+ {
+ DateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
+ Date d = df.parse(cell.toString());
+ values.put(ColumnName.CARD_EXPIRE, d);
}
- else {
- throw new ApiUsageException("Unrecognized type in date column");
+ }
+
+ 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));
+ }
}
+ }
- values.put(columnName, value);
+ String value = "";
+ if (cell.getCellType() == CellType.STRING) {
+ value = cell.getStringCellValue();
}
- else {
- //For whatever reason apache ROI library thinks some of these cells are numeric,
- //Even though excel says they are text
- String value;
- if (cell.getCellType() == CellType.NUMERIC) {
- value = NumberToTextConverter.toText(cell.getNumericCellValue());
- }
- else {
- value = cell.getStringCellValue();
- }
+ if (!values.containsKey(columnName))
values.put(columnName, value);
- }
}
}
- Pair pair = new Pair<>(new CardInfo(values), new AccessInfo(values));
+ Pair pair = new Pair<>(new CardInfo(values), new AccessInfo(values));
return pair;
}
@@ -153,29 +178,26 @@ public String getLastName() {
return (String) this.values.get(ColumnName.LAST_NAME);
}
- public String getDepartment() {
- return (String) this.values.get(ColumnName.DEPARTMENT);
- }
-
public String getCardNumber() {
return (String) this.values.get(ColumnName.CARD_NUMBER);
}
-
- public String getEmployeeNumber() {
- return (String) this.values.get(ColumnName.EMPLOYEE_NUMBER);
+ public Date getCardIssued() {
+ return (Date) this.values.get(ColumnName.CARD_ISSUED);
}
-
- public String getInfo2() {
- return (String) this.values.get(ColumnName.INFO2);
+ public Date getCardExpire() {
+ return (Date) this.values.get(ColumnName.CARD_EXPIRE);
}
-
- public String getInfo3() {
- return (String) this.values.get(ColumnName.INFO3);
+ public String getIssueCode() {
+ return (String) this.values.get(ColumnName.CARD_ISSUE_CODE);
+ }
+ public String getCardType() {
+ return (String) this.values.get(ColumnName.BADGE_TYPE);
}
- public String getInfo5() {
- return (String) this.values.get(ColumnName.INFO5);
+ public Map getValues() {
+ return this.values;
}
+
}
public static class AccessInfo {
@@ -185,26 +207,6 @@ public AccessInfo(Map values) {
this.values = values;
}
- public String getSchedule() {
- return (String) this.values.get(ColumnName.SCHEDULE_PT);
- }
-
- public Date getLastEntered() {
- return (Date) this.values.get(ColumnName.TIME_ENTERED);
- }
-
- public boolean isEnabled() {
- String state = (String) this.values.get(ColumnName.STATE);
- if (state.equalsIgnoreCase("Enabled") || state.equalsIgnoreCase("")) {
- return true;
- }
- else if (state.equalsIgnoreCase("DISABLED")) {
- return false;
- }
- else {
- throw new ApiUsageException("Unrecognized value in 'state' column: " + state);
- }
- }
}
public static class MalformedReportException extends Exception {
@@ -214,7 +216,7 @@ public MalformedReportException(String message) {
}
public static Date parseDate(String dateString) {
- SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a");
+ SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ssa");
SimpleDateFormat shortDateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date date;
diff --git a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportService.java b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportService.java
index 23220f2f6..576ba1a7c 100644
--- a/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportService.java
+++ b/WNPRC_Compliance/src/org/labkey/wnprc_compliance/AccessReportService.java
@@ -3,7 +3,9 @@
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
import org.json.JSONObject;
+import org.junit.Assert;
import org.labkey.api.action.ApiUsageException;
import org.labkey.api.data.CompareType;
import org.labkey.api.data.Container;
@@ -15,6 +17,7 @@
import org.labkey.api.query.DuplicateKeyException;
import org.labkey.api.query.InvalidKeyException;
import org.labkey.api.query.QueryUpdateServiceException;
+import org.labkey.api.reader.ExcelLoader;
import org.labkey.api.security.User;
import org.labkey.api.util.JsonUtil;
import org.labkey.api.util.Pair;
@@ -26,6 +29,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
+import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
@@ -50,24 +54,30 @@ public AccessReportService(User user, Container container) {
this.container = container;
}
- public void importReport(InputStream stream) throws IOException, AccessReportRowParser.MalformedReportException {
+ public void importReport(InputStream stream) throws IOException, AccessReportRowParser.MalformedReportException, ParseException
+ {
String reportid = UUID.randomUUID().toString().toUpperCase();
+ Sheet sheet = new ExcelLoader(stream,false, null).getSheet();
- HSSFWorkbook workbook = new HSSFWorkbook(stream);
- HSSFSheet sheet = workbook.getSheetAt(0);
-
- Row titleRow = sheet.getRow(2);
- if (!titleRow.getCell(0).getStringCellValue().equalsIgnoreCase("Area Rights Report")) {
+ Row titleRow = sheet.getRow(1);
+ if (!titleRow.getCell(0).getStringCellValue().equalsIgnoreCase("Access Level Assignments to Cardholders")) {
throw new ApiUsageException("You can only upload area rights reports here.");
}
Row dateRow = sheet.getRow(6);
- Pattern datePattern = Pattern.compile("report created on (.*)");
- Matcher datePatternMatcher = datePattern.matcher(dateRow.getCell(0).getStringCellValue());
- if (!datePatternMatcher.matches()) {
- throw new ApiUsageException("Could not parse date of report");
+ //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());
+ String reportDateTime;
+ Date generatedOn;
+ if (matcher.find())
+ {
+ reportDateTime = matcher.group(1).trim();
+ generatedOn = AccessReportRowParser.parseDate(reportDateTime);
+ }
+ else
+ {
+ throw new ApiUsageException("Unable to parse date/time string");
}
- Date generatedOn = AccessReportRowParser.parseDate(datePatternMatcher.group(1));
// Check to make sure we haven't done this already.
SimpleQueryFactory queryFactory = new SimpleQueryFactory(user, container);
@@ -77,84 +87,103 @@ public void importReport(InputStream stream) throws IOException, AccessReportRow
throw new ApiUsageException("This report has already been uploaded.");
}
- Set areaNames = new HashSet<>();
Map cardInfos = new HashMap<>();
List