From 2bfdcfa1585088c16082bbaa4a93228d10f3cae6 Mon Sep 17 00:00:00 2001 From: LeviCameron1 <86750204+LeviCameron1@users.noreply.github.com> Date: Tue, 25 Nov 2025 17:21:44 -0600 Subject: [PATCH 1/4] Add new tests to hematology bulk upload (#900) * Add tests for RDW-CV and RDW-SD to hematology results * Remove ctrl + x bulk upload function for hematology results --- .../resources/web/ehr/ext3/ExtContainers.js | 83 +++--- .../resources/web/wnprc_ehr/wnprcOverRides.js | 241 +----------------- 2 files changed, 43 insertions(+), 281 deletions(-) diff --git a/WNPRC_EHR/resources/web/ehr/ext3/ExtContainers.js b/WNPRC_EHR/resources/web/ehr/ext3/ExtContainers.js index 794369e17..a49138188 100644 --- a/WNPRC_EHR/resources/web/ehr/ext3/ExtContainers.js +++ b/WNPRC_EHR/resources/web/ehr/ext3/ExtContainers.js @@ -974,7 +974,7 @@ EHR.ext.HematologyExcelWin = Ext.extend(Ext.Panel, { tests = {}; //result.animalId = row1[2].substr(0,6); - result.animalId = row1.substr(27,6); + result.animalId = row1.substring(27,33); result.animalId = result.animalId.toLowerCase(); var requestNumber = runsStore.find('Id',result.animalId) @@ -997,40 +997,41 @@ EHR.ext.HematologyExcelWin = Ext.extend(Ext.Panel, { return; } - tests['WBC'] = row2.substr(6,6); - tests['RBC'] = row2.substr(12,5); - tests['HGB'] = row2.substr(17,5); - tests['HCT'] = row2.substr(22,5); - tests['MCV'] = row2.substr(27,5); - tests['MCH'] = row2.substr(32,5); - tests['MCHC'] = row2.substr(37,5); - tests['PLT'] = row2.substr(42,5); - //tests['LYMPH%'] = row2.substr(47,5); - tests['LY'] = row2.substr(47,5); - - //tests['MONO%'] = row2.substr(52,5); - tests['MN'] = row2.substr(52,5); - - //tests['SEG%'] = row2.substr(57,5); - tests['NE'] = row2.substr(57,5); - - //tests['EOSIN%'] = row2.substr(62,5); - tests['EO'] = row2.substr(62,5); - - //tests['BASO%'] = row2.substr(67,5); - tests['BS'] = row2.substr(67,5); - - //tests['LYMPH#'] = row2.substr(72,6); - //tests['MONO#'] = row2.substr(78,6); - //tests['SEG#'] = row2.substr(84,6); - //tests['EOSIN#'] = row2.substr(90,6); - //tests['BASO#'] = row2.substr(96,6); - tests['RDW'] = row2.substr(102,5); - //tests'RDW-CV'] = row2.substr(102,5); - //tests['RDW-SD'] = row2.substr(107,5); - //tests['PDW'] = row2.substr(112,5); - tests['MPV'] = row2.substr(117,5); - //tests['P-LCR'] = row2.substr(122,5); + tests['WBC'] = row2.substring(6, 12); + tests['RBC'] = row2.substring(12, 17); + tests['HGB'] = row2.substring(17, 22); + tests['HCT'] = row2.substring(22, 27); + tests['MCV'] = row2.substring(27, 32); + tests['MCH'] = row2.substring(32, 37); + tests['MCHC'] = row2.substring(37, 42); + tests['PLT'] = row2.substring(42, 47); + //tests['LYMPH%'] = row2.substring(47, 52); + tests['LY'] = row2.substring(47, 52); + + //tests['MONO%'] = row2.substring(52, 57); + tests['MN'] = row2.substring(52, 57); + + //tests['SEG%'] = row2.substring(57, 62); + tests['NE'] = row2.substring(57, 62); + + //tests['EOSIN%'] = row2.substring(62, 67); + tests['EO'] = row2.substring(62, 67); + + //tests['BASO%'] = row2.substring(67, 72); + tests['BS'] = row2.substring(67, 72); + + //tests['LYMPH#'] = row2.substring(72, 78); + //tests['MONO#'] = row2.substring(78, 84); + //tests['SEG#'] = row2.substring(84, 90); + //tests['EOSIN#'] = row2.substring(90, 96); + //tests['BASO#'] = row2.substring(96, 102); + //tests['RDW'] = row2.substring(102, 107); + tests['RDW-CV'] = row2.substring(102, 107); + tests['RDW-SD'] = row2.substring(107, 112); + //tests['PDW'] = row2.substring(112, 117); + tests['MPV'] = row2.substring(117, 122); + //tests['P-LCR'] = row2.substring(122, 127); + var value; for(var test in tests){ @@ -1038,25 +1039,25 @@ EHR.ext.HematologyExcelWin = Ext.extend(Ext.Panel, { value = tests[test]; if (value.match(/^00(\d){4}$/)) { - tests[test] = value.substr(2,3) / 100; + tests[test] = value.substring(2,5) / 100; } //note: at the moment WBC is the only test with 6 chars, so this test is possibly redundant else if (value.match(/^0(\d){4,}$/) && test=='WBC') { - tests[test] = value.substr(1,4) / 100; + tests[test] = value.substring(1,5) / 100; } else if (value.match(/^0\d{4}$/)){ if (test=='RBC') { - tests[test] = value.substr(1,3) / 100; + tests[test] = value.substring(1,4) / 100; } else if (test=='PLT') { - tests[test] = value.substr(1,3) / 1; //convert to number + tests[test] = value.substring(1,4) / 1; //convert to number } else { - tests[test] = value.substr(1,3) / 10; + tests[test] = value.substring(1,4) / 10; } } else if (test=='PLT') { - tests[test] = value.substr(0,4); + tests[test] = value.substring(0,4); } //NOTE: the following is a possible replacement for the logic above diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/wnprcOverRides.js b/WNPRC_EHR/resources/web/wnprc_ehr/wnprcOverRides.js index aee736c2a..5ef15c5f1 100644 --- a/WNPRC_EHR/resources/web/wnprc_ehr/wnprcOverRides.js +++ b/WNPRC_EHR/resources/web/wnprc_ehr/wnprcOverRides.js @@ -819,243 +819,4 @@ EHR.Metadata.registerMetadata('NewAnimal', { } } } -}); - -/* - * This (the rest of this file) is a patch for the Hematology bulk add button, to fix issue WNPRC#4430. - * However, as it duplicates code from ExtContainers.js and ehrGridFormPanel.js, it is only meant as - * a temporary solution until a more permanent solution can be formulated. - */ -WNPRC_EHR.HematologyBulkAdd = Ext.extend(Ext.Panel, { - initComponent: function() { - Ext.applyIf(this, { - title: 'Enter Hematology From Sysmex Analyzer', - bodyBorder: true, - border: true, - bodyStyle: 'padding:5px', - width: '100%', - defaults: { - border: false, - bodyBorder: false - }, - items: [ - { - xtype: 'displayfield', - value: 'This allows bulk import of hematology results using the output of a Sysmex Hematology Analyzer. Cut/paste the contents of the output below.' - },{ - xtype: 'textarea', - ref: 'fileField', - height: 350, - width: 430 - } - ], - buttons: [{ - text:'Submit', - disabled:false, - ref: '../submit', - scope: this, - handler: function(s){ - this.processData(); - } - },{ - text: 'Close', - scope: this, - handler: function(){ - this.ownerCt.hide(); - } - }] - }); - - EHR.ext.HematologyExcelWin.superclass.initComponent.call(this, arguments); - }, - processData: function(){ - var data = this.fileField.getValue(); - - if (!data) { - alert('Must Paste Contents of File'); - return; - } - - var skippedRows = []; - - var hematologyResults = Ext.StoreMgr.get("study||Hematology Results||||"); - var runsStore = Ext.StoreMgr.get("study||Clinpath Runs||||"); - var unitStore = Ext.StoreMgr.get("ehr_lookups||hematology_tests||testid||testid"); - - var result; - var tests; - var row1; - var row2; - var toAdd = []; - - if(!data.length || !data[0].length){ - alert('Something went wrong processing the file'); - console.log(data); - return; - } - - data = data.split(/D1U/i); - - Ext.each(data, function(row, idx){ - if(!row.match(/D2U/i)) - return; - - row = row.split(/D2U/i); - - row1 = row[0]; - row2 = row[1]; - row1 = row1.replace(/\s+/g, ''); - row2 = row2.split(/\s+/); - row2 = row2.slice(2, row2.length-1); - row2 = row2.join(''); - - result = {}; - tests = {}; - - result.animalId = row1.substr(27,6); - result.animalId = result.animalId.toLowerCase(); - - var requestNumber = runsStore.find('Id',result.animalId) - var record = runsStore.getAt(requestNumber); - - //Getting the collection time from the request itself, if it matches animalId - if(requestNumber!= -1 && result.animalId == record.get('Id')){ - - var collectionDate = record.get('date'); - } - - result.date= new Date(collectionDate); - - if(!result.animalId || runsStore.find('Id', result.animalId)==-1){ - //alert('ID: '+result.animalId+' not found in Clinpath Runs section. Records will not be added'); - skippedRows.push('Not found in Clinpath Runs: '+result.animalId); - return; - } - - tests['WBC'] = row2.substr(6,6); - tests['RBC'] = row2.substr(12,5); - tests['HGB'] = row2.substr(17,5); - tests['HCT'] = row2.substr(22,5); - tests['MCV'] = row2.substr(27,5); - tests['MCH'] = row2.substr(32,5); - tests['MCHC'] = row2.substr(37,5); - tests['PLT'] = row2.substr(42,5); - //tests['LYMPH%'] = row2.substr(47,5); - tests['LY'] = row2.substr(47,5); - - //tests['MONO%'] = row2.substr(52,5); - tests['MN'] = row2.substr(52,5); - - //tests['SEG%'] = row2.substr(57,5); - tests['NE'] = row2.substr(57,5); - - //tests['EOSIN%'] = row2.substr(62,5); - tests['EO'] = row2.substr(62,5); - - //tests['BASO%'] = row2.substr(67,5); - tests['BS'] = row2.substr(67,5); - - //tests['LYMPH#'] = row2.substr(72,6); - //tests['MONO#'] = row2.substr(78,6); - //tests['SEG#'] = row2.substr(84,6); - //tests['EOSIN#'] = row2.substr(90,6); - //tests['BASO#'] = row2.substr(96,6); - tests['RDW'] = row2.substr(102,5); - //tests'RDW-CV'] = row2.substr(102,5); - //tests['RDW-SD'] = row2.substr(107,5); - //tests['PDW'] = row2.substr(112,5); - tests['MPV'] = row2.substr(117,5); - //tests['P-LCR'] = row2.substr(122,5); - - var value; - for(var test in tests){ - var origVal = tests[test]; - value = tests[test]; - - if (value.match(/^00(\d){4}$/)) { - tests[test] = value.substr(2,3) / 100; - } - //note: at the moment WBC is the only test with 6 chars, so this test is possibly redundant - else if (value.match(/^0(\d){4,}$/) && test=='WBC') { - tests[test] = value.substr(1,4) / 100; - } - else if (value.match(/^0\d{4}$/)){ - if (test=='RBC') { - tests[test] = value.substr(1,3) / 100; - } - else if (test=='PLT') { - tests[test] = value.substr(1,3) / 1; //convert to number - } - else { - tests[test] = value.substr(1,3) / 10; - } - } - else if (test=='PLT') { - tests[test] = value.substr(0,4); - } - - //find units - var idx = unitStore.find('testid', test); - var units = null; - var sortOrder = null; - if(idx!=-1){ - units = unitStore.getAt(idx).get('units'); - sortOrder = unitStore.getAt(idx).get('sort_order'); - } - - if(tests[test] && isNaN(tests[test])){ - skippedRows.push('Invalid Result for: '+result.animalId+', TestId: '+test+', '+tests[test]); - tests[test] = null; - } - - toAdd.push({ - Id: result.animalId, - date: result.date, - testid: test, - result: tests[test], - units: units, - sortOrder: sortOrder - }); - } - - }, this); - - if(toAdd.length){ - toAdd.sort(function(a, b){ - return a.Id < b.Id ? -1 : - a.Id > b.Id ? 1 : - a.date < b.date ? -1 : - a.date > b.date ? 1 : - a.sortOrder < b.sortOrder ? -1 : - a.sortOrder > b.sortOrder ? 1 : - 0 - }); - hematologyResults.addRecords(toAdd); - } - - if(skippedRows.length){ - alert('One or more rows were skipped:\n'+skippedRows.join('\n')); - } - } -}); -Ext.reg('wnprc_ehr-hematologybulkadd', WNPRC_EHR.HematologyBulkAdd); - -/* - * Let Ctrl+x open the popup - */ -WNPRC_EHR.HematologyPopup = function() { - var popup = new Ext.Window({ - closeAction:'hide', - width: 450, - items: [{ - xtype: 'wnprc_ehr-hematologybulkadd' - }] - }); - - popup.show(); -}; -jQuery(document).on('keypress', function(e){ - if (e.ctrlKey && (e.which == 24)) { - WNPRC_EHR.HematologyPopup(); - } -}); +}); \ No newline at end of file From 0a035236bc502e7c6ef4ab8892c76d8351485807 Mon Sep 17 00:00:00 2001 From: LeviCameron1 <86750204+LeviCameron1@users.noreply.github.com> Date: Tue, 25 Nov 2025 17:22:03 -0600 Subject: [PATCH 2/4] TB Dashboard Access Report Upload (#898) * Starting work on updating access report import * Update barrier access report to work with workday style excel sheets --- .../MostRecentAccessReportSummary.sql | 90 +++++------------- .../AccessReportRowParser.java | 84 ++++++----------- .../wnprc_compliance/AccessReportService.java | 91 ++++--------------- .../WNPRC_ComplianceController.java | 2 +- 4 files changed, 68 insertions(+), 199 deletions(-) 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) { From 62acf47f88a1c121e6aa909ecdb47569ef4aa439 Mon Sep 17 00:00:00 2001 From: "F. Daniel Nicolalde" Date: Fri, 28 Nov 2025 17:12:06 -0500 Subject: [PATCH 3/4] 25.7 fb workdaychanges (#901) * Changing labels to the columns to match WorkDay new names * Adding new column to the aliases table * Adding new template for creating new accounts * Adding columns to JET export and adding column to aliases * expand workday export to include new columns for EIB * simplifying work day display for CSV export * removing program from aliases table since it is not needed * Changing Fund-account to Grant removing UW Fund * Adding class for new csv export and removing institution --- .../domain-templates/ehr_billing.template.xml | 4 + .../queries/ehr_billing/aliases.query.xml | 31 ++- .../queries/ehr_billing/aliases/.qview.xml | 2 + .../queries/ehr_billing/aliasesTemplate.sql | 40 ++++ .../ehr_billing/invoiceRuns/.qview.xml | 10 + .../workdayInvoiceItems.query.xml | 31 +++ .../wnprc_billing/workdayInvoiceItems.sql | 27 +++ .../workdayInvoiceItems/.qview.xml | 21 +++ .../WNPRC_BillingController.java | 178 ++++++++++++++++++ .../wnprc_billing/WNPRC_BillingSchema.java | 1 + .../WNPRC_InvoiceRunCustomizer.java | 44 +++++ .../wnprc_billing/invoice/InvoicePDF.java | 4 +- 12 files changed, 386 insertions(+), 7 deletions(-) create mode 100644 wnprc_billing/resources/queries/ehr_billing/aliasesTemplate.sql create mode 100644 wnprc_billing/resources/queries/wnprc_billing/workdayInvoiceItems.query.xml create mode 100644 wnprc_billing/resources/queries/wnprc_billing/workdayInvoiceItems.sql create mode 100644 wnprc_billing/resources/queries/wnprc_billing/workdayInvoiceItems/.qview.xml diff --git a/wnprc_billing/resources/domain-templates/ehr_billing.template.xml b/wnprc_billing/resources/domain-templates/ehr_billing.template.xml index 6851deaa2..a8bc76b86 100644 --- a/wnprc_billing/resources/domain-templates/ehr_billing.template.xml +++ b/wnprc_billing/resources/domain-templates/ehr_billing.template.xml @@ -114,6 +114,10 @@ string 500 + + string + 500 + diff --git a/wnprc_billing/resources/queries/ehr_billing/aliases.query.xml b/wnprc_billing/resources/queries/ehr_billing/aliases.query.xml index d3d47a4f0..cab48c802 100644 --- a/wnprc_billing/resources/queries/ehr_billing/aliases.query.xml +++ b/wnprc_billing/resources/queries/ehr_billing/aliases.query.xml @@ -3,11 +3,17 @@ + +