@Override public EncounterQueryResult evaluate(EncounterQuery definition, EvaluationContext context) throws EvaluationException { context = ObjectUtil.nvl(context, new EvaluationContext()); BasicEncounterQuery query = (BasicEncounterQuery) definition; EncounterQueryResult result = new EncounterQueryResult(query, context); if (context.getBaseCohort() != null && context.getBaseCohort().isEmpty()) { return result; } if (context instanceof EncounterEvaluationContext) { EncounterIdSet baseEncounters = ((EncounterEvaluationContext) context).getBaseEncounters(); if (baseEncounters != null && baseEncounters.getMemberIds().isEmpty()) { return result; } } HqlQueryBuilder q = new HqlQueryBuilder(); q.select("e.encounterId"); q.from(Encounter.class, "e"); q.whereIn("e.encounterType", query.getEncounterTypes()); q.whereIn("e.form", query.getForms()); q.whereGreaterOrEqualTo("e.encounterDatetime", query.getOnOrAfter()); q.whereLessOrEqualTo("e.encounterDatetime", query.getOnOrBefore()); q.whereIn("e.location", query.getLocationList()); q.whereEncounterIn("e.encounterId", context); if (query.getWhich() == null || query.getWhich() == TimeQualifier.ANY) { List<Integer> results = evaluationService.evaluateToList(q, Integer.class); result.getMemberIds().addAll(results); } else { q.innerJoin("e.patient", "p"); q.select("p.patientId"); if (query.getWhich() == TimeQualifier.LAST) { q.orderDesc("e.encounterDatetime"); } else { q.orderAsc("e.encounterDatetime"); } ListMap<Integer, Integer> foundEncountersForPatients = new ListMap<Integer, Integer>(); int maxNumPerPatient = ObjectUtil.nvl(query.getWhichNumber(), 1); for (Object[] row : evaluationService.evaluateToList(q)) { Integer encounterId = (Integer) row[0]; Integer patientId = (Integer) row[1]; foundEncountersForPatients.putInList(patientId, encounterId); if (foundEncountersForPatients.get(patientId).size() <= maxNumPerPatient) { result.add(encounterId); } } } return result; }
@Override public void started() { log.info("pihmalawi module started - initializing..."); for (Initializer initializer : getInitializers()) { initializer.started(); } // New bug/feature in Chrome/IE/Safari causes system to log out user with default logo link url. // Update this here. List<AllFreeStandingExtensions> l = Context.getRegisteredComponents(AllFreeStandingExtensions.class); if (l != null && l.size() > 0) { AllFreeStandingExtensions extensions = l.get(0); Map<String, Object> extensionParams = ObjectUtil.toMap("logo-link-url", "/index.htm"); Extension e = new Extension( "pihmalawi.headerExtension", null, AppUiExtensions.HEADER_CONFIG_EXTENSION, null, null, null, 100, null, extensionParams); extensions.add(e); } }
@Override public EncounterQueryResult evaluate(EncounterQuery definition, EvaluationContext context) throws EvaluationException { context = ObjectUtil.nvl(context, new EvaluationContext()); BasicEncounterQuery query = (BasicEncounterQuery) definition; EncounterQueryResult result = new EncounterQueryResult(query, context); Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Encounter.class); criteria.setProjection(Projections.id()); criteria.add(Restrictions.eq("voided", false)); if (query.getOnOrAfter() != null) { criteria.add(Restrictions.ge("encounterDatetime", query.getOnOrAfter())); } if (query.getOnOrBefore() != null) { criteria.add( Restrictions.le( "encounterDatetime", DateUtil.getEndOfDayIfTimeExcluded(query.getOnOrBefore()))); } if (context.getBaseCohort() != null) { if (context.getBaseCohort().size() == 0) { return result; } else { criteria.add(Restrictions.in("patient.id", context.getBaseCohort().getMemberIds())); } } if (context instanceof EncounterEvaluationContext) { EncounterIdSet baseEncounters = ((EncounterEvaluationContext) context).getBaseEncounters(); if (baseEncounters != null) { if (baseEncounters.getSize() == 0) { return result; } else { criteria.add(Restrictions.in("id", baseEncounters.getMemberIds())); } } } for (Integer encounterId : ((List<Integer>) criteria.list())) { result.add(encounterId); } return result; }
/** * @see DataSetEvaluator#evaluate(DataSetDefinition, EvaluationContext) * @should evaluate an EncounterAndObsDataSetDefinition */ public DataSet evaluate(DataSetDefinition dataSetDefinition, EvaluationContext context) throws EvaluationException { EncounterAndObsDataSetDefinition definition = (EncounterAndObsDataSetDefinition) dataSetDefinition; SimpleDataSet dataSet = new SimpleDataSet(dataSetDefinition, context); context = ObjectUtil.nvl(context, new EvaluationContext()); Cohort cohort = context.getBaseCohort(); if (context.getLimit() != null) { CohortUtil.limitCohort(cohort, context.getLimit()); } // Retrieve the rows for the dataset BasicEncounterQuery encounterQuery = new BasicEncounterQuery(); encounterQuery.setWhich(definition.getWhichEncounterQualifier()); encounterQuery.setWhichNumber(definition.getQuantity()); encounterQuery.setEncounterTypes(definition.getEncounterTypes()); encounterQuery.setForms(definition.getForms()); encounterQuery.setOnOrBefore(definition.getEncounterDatetimeOnOrBefore()); encounterQuery.setOnOrAfter(definition.getEncounterDatetimeOnOrAfter()); EncounterQueryResult encounterIdRows = encounterQueryService.evaluate(encounterQuery, context); HqlQueryBuilder q = new HqlQueryBuilder(); EncounterEvaluationContext eec = new EncounterEvaluationContext(); eec.setBaseEncounters(encounterIdRows); q.from(Encounter.class, "e").whereEncounterIn("e.encounterId", eec); List<Encounter> encounters = evaluationService.evaluateToList(q, Encounter.class); // Determine what columns to display in the dataset List<EncounterAndObsDataSetDefinition.ObsOptionalColumn> optionalColumns = definition.getOptionalColumns(); List<PatientIdentifierType> patientIdentifierTypes = definition.getPatientIdentifierTypes(); List<EncounterAndObsDataSetDefinition.ColumnDisplayFormat> columnDisplayFormat = definition.getColumnDisplayFormat(); Integer maxColumnHeaderWidth = definition.getMaxColumnHeaderWidth(); if (patientIdentifierTypes == null) { patientIdentifierTypes = new ArrayList<PatientIdentifierType>(); } if (columnDisplayFormat == null) { columnDisplayFormat = new ArrayList<ColumnDisplayFormat>(); } if (columnDisplayFormat.size() == 0) { columnDisplayFormat.add(EncounterAndObsDataSetDefinition.ColumnDisplayFormat.ID); } // section index should be added here // Store all encounters within a data structure that keeps track of obs, obs groups, and their // occurrences // in order that column headers are unique and children obs are grouped by their parent Map<Encounter, Map<ObsColumnDescriptor, Obs>> populatedFieldMap = populateFieldMap(encounters); // Keeps track of the column headers for all obs-related columns Set<ObsColumnDescriptor> allColumns = new TreeSet<ObsColumnDescriptor>(); for (Encounter encounter : encounters) { Map<ObsColumnDescriptor, Obs> obsInEncounter = populatedFieldMap.get(encounter); // Not all encounters will have data for all columns but // each encounter row should have all column headers // so encounters line up properly under a common set of column headers allColumns.addAll(obsInEncounter.keySet()); } // add the data to the DataSet return addData( dataSet, encounters, patientIdentifierTypes, optionalColumns, columnDisplayFormat, maxColumnHeaderWidth, allColumns, populatedFieldMap); }
/** * Adds the column headers and column data to the DataSet * * @param dataSet * @param encounters * @param patientIdentifierTypes * @param optionalColumns * @param columnDisplayFormat * @param maxColumnHeaderWidth * @param allColumns * @param fieldMap * @return */ public DataSet addData( SimpleDataSet dataSet, List<Encounter> encounters, List<PatientIdentifierType> patientIdentifierTypes, List<EncounterAndObsDataSetDefinition.ObsOptionalColumn> optionalColumns, List<EncounterAndObsDataSetDefinition.ColumnDisplayFormat> columnDisplayFormat, Integer maxColumnHeaderWidth, Set<ObsColumnDescriptor> allColumns, Map<Encounter, Map<ObsColumnDescriptor, Obs>> fieldMap) { for (Encounter encounter : encounters) { DataSetRow row = new DataSetRow(); List<String> providerNames = new ArrayList<String>(); for (EncounterProvider ep : encounter.getEncounterProviders()) { providerNames.add(ep.getProvider().getName()); } // Add the standard columns for encounters DataSetColumn c1 = new DataSetColumn( ObjectUtil.trimStringIfNeeded("ENCOUNTER_ID", maxColumnHeaderWidth), ObjectUtil.trimStringIfNeeded("ENCOUNTER_ID", maxColumnHeaderWidth), Integer.class); row.addColumnValue(c1, encounter.getEncounterId()); DataSetColumn c2 = new DataSetColumn( ObjectUtil.trimStringIfNeeded("ENCOUNTER_DATETIME", maxColumnHeaderWidth), ObjectUtil.trimStringIfNeeded("ENCOUNTER_DATETIME", maxColumnHeaderWidth), String.class); row.addColumnValue(c2, encounter.getEncounterDatetime().toString()); DataSetColumn c3 = new DataSetColumn( ObjectUtil.trimStringIfNeeded("LOCATION", maxColumnHeaderWidth), ObjectUtil.trimStringIfNeeded("LOCATION", maxColumnHeaderWidth), String.class); row.addColumnValue( c3, (encounter.getLocation() != null) ? encounter.getLocation().getName() : EMPTY); DataSetColumn c4 = new DataSetColumn( ObjectUtil.trimStringIfNeeded("PROVIDER", maxColumnHeaderWidth), ObjectUtil.trimStringIfNeeded("PROVIDER", maxColumnHeaderWidth), String.class); row.addColumnValue(c4, OpenmrsUtil.join(providerNames, ", ")); DataSetColumn c5 = new DataSetColumn( ObjectUtil.trimStringIfNeeded("INTERNAL_PATIENT_ID", maxColumnHeaderWidth), ObjectUtil.trimStringIfNeeded("INTERNAL_PATIENT_ID", maxColumnHeaderWidth), Integer.class); row.addColumnValue( c5, encounter.getPatient() != null ? encounter.getPatient().getPatientId() : EMPTY); if (patientIdentifierTypes != null) { for (PatientIdentifierType pit : patientIdentifierTypes) { List<PatientIdentifier> patientIdentifiers = encounter.getPatient().getPatientIdentifiers(pit); StringBuffer sbPatientIdentifiers = new StringBuffer(); int count = 0; for (PatientIdentifier patientIdentifier : patientIdentifiers) { if (count > 0) { sbPatientIdentifiers.append(", "); } sbPatientIdentifiers.append(patientIdentifier.toString()); count++; } DataSetColumn c6 = new DataSetColumn( pit.getName(), ObjectUtil.trimStringIfNeeded(pit.getName(), maxColumnHeaderWidth), String.class); row.addColumnValue(c6, sbPatientIdentifiers.toString()); } } Map<ObsColumnDescriptor, Obs> obsInEncounter = fieldMap.get(encounter); // Look up all obs for a given encounter based on column headers for all encounters for (ObsColumnDescriptor columnKey : allColumns) { Obs obs = obsInEncounter.get(columnKey); String columnName = columnKey.format(columnDisplayFormat, maxColumnHeaderWidth); DataSetColumn obsDsc = new DataSetColumn(columnName, columnName, String.class); StringBuffer columnValue = new StringBuffer(); if (obs != null && obs.getValueCoded() != null) { if (columnDisplayFormat.contains( EncounterAndObsDataSetDefinition.ColumnDisplayFormat.ID)) { columnValue.append(obs.getValueCoded()); } if (columnDisplayFormat.contains(EncounterAndObsDataSetDefinition.ColumnDisplayFormat.ID) && columnDisplayFormat.contains( EncounterAndObsDataSetDefinition.ColumnDisplayFormat.BEST_SHORT_NAME)) { columnValue.append("_"); } if (columnDisplayFormat.contains( EncounterAndObsDataSetDefinition.ColumnDisplayFormat.BEST_SHORT_NAME)) { String conceptName = obs.getValueAsString(Context.getLocale()); columnValue.append( maxColumnHeaderWidth != null && conceptName.length() > maxColumnHeaderWidth - columnValue.length() ? conceptName.substring(0, maxColumnHeaderWidth - columnValue.length() - 1) : conceptName); } row.addColumnValue(obsDsc, (obs != null) ? columnValue.toString() : EMPTY); } else { row.addColumnValue( obsDsc, (obs != null) ? obs.getValueAsString(Context.getLocale()) : EMPTY); } String dateColumnName = columnKey.format( columnDisplayFormat, maxColumnHeaderWidth != null ? maxColumnHeaderWidth - 5 : null); DataSetColumn obsDscDate = new DataSetColumn(dateColumnName + "_DATE", dateColumnName + "_DATE", String.class); row.addColumnValue(obsDscDate, (obs != null) ? obs.getObsDatetime().toString() : EMPTY); String parentColumnName = columnKey.format( columnDisplayFormat, maxColumnHeaderWidth != null ? maxColumnHeaderWidth - 7 : null); DataSetColumn obsDscParent = new DataSetColumn( parentColumnName + "_PARENT", parentColumnName + "_PARENT", String.class); row.addColumnValue( obsDscParent, (obs != null && obs.getObsGroup() != null) ? obs.getObsGroup().getId() : EMPTY); if (optionalColumns != null) { if (optionalColumns.contains( EncounterAndObsDataSetDefinition.ObsOptionalColumn.VALUE_MODIFIER)) { String valModColumnName = columnKey.format( columnDisplayFormat, maxColumnHeaderWidth != null ? maxColumnHeaderWidth - 10 : null); DataSetColumn obsDscValueModifier = new DataSetColumn( valModColumnName + "_VALUE_MOD", valModColumnName + "_VALUE_MOD", String.class); row.addColumnValue(obsDscValueModifier, (obs != null) ? obs.getValueModifier() : EMPTY); } if (optionalColumns.contains( EncounterAndObsDataSetDefinition.ObsOptionalColumn.ACCESSION_NUMBER)) { String accessionNumColumnName = columnKey.format( columnDisplayFormat, maxColumnHeaderWidth != null ? maxColumnHeaderWidth - 14 : null); DataSetColumn obsDscAccessionNumber = new DataSetColumn( accessionNumColumnName + "_ACCESSION_NUM", accessionNumColumnName + "_ACCESSION_NUM", String.class); row.addColumnValue( obsDscAccessionNumber, (obs != null) ? obs.getAccessionNumber() : EMPTY); } if (optionalColumns.contains( EncounterAndObsDataSetDefinition.ObsOptionalColumn.COMMENT)) { String commentColumnName = columnKey.format( columnDisplayFormat, maxColumnHeaderWidth != null ? maxColumnHeaderWidth - 8 : null); DataSetColumn obsDscComment = new DataSetColumn( commentColumnName + "_COMMENT", commentColumnName + "_COMMENT", String.class); row.addColumnValue(obsDscComment, (obs != null) ? obs.getComment() : EMPTY); } } } dataSet.addRow(row); } return dataSet; }
/** * @see CohortDefinitionEvaluator#evaluateCohort(CohortDefinition, EvaluationContext) * @should return patients who have identifiers of the passed types * @should return patients who have identifiers matching the passed locations * @should return patients who have identifiers matching the passed text * @should return patients who have identifiers matching the passed regular expression */ public EvaluatedCohort evaluate(CohortDefinition cohortDefinition, EvaluationContext context) { PatientIdentifierCohortDefinition picd = (PatientIdentifierCohortDefinition) cohortDefinition; StringBuilder hql = new StringBuilder(); Map<String, Object> params = new HashMap<String, Object>(); hql.append("select patient.patientId"); hql.append(ObjectUtil.notNull(picd.getRegexToMatch()) ? ", identifier " : " "); hql.append("from PatientIdentifier "); hql.append("where voided = false "); if (picd.getTypesToMatch() != null) { Set<Integer> typeIds = new HashSet<Integer>(); for (PatientIdentifierType t : picd.getTypesToMatch()) { typeIds.add(t.getPatientIdentifierTypeId()); } hql.append("and identifierType.patientIdentifierTypeId in (:idTypes) "); params.put("idTypes", typeIds); } if (picd.getLocationsToMatch() != null) { Set<Integer> locationIds = new HashSet<Integer>(); for (Location l : picd.getLocationsToMatch()) { locationIds.add(l.getLocationId()); } hql.append("and location.locationId in (:locationIds) "); params.put("locationIds", locationIds); } if (ObjectUtil.notNull(picd.getTextToMatch())) { if (picd.getTextToMatch().contains("%")) { hql.append("and identifier like :textToMatch "); } else { hql.append("and identifier = :textToMatch "); } params.put("textToMatch", picd.getTextToMatch()); } List<Object> results = Context.getService(DataSetQueryService.class).executeHqlQuery(hql.toString(), params); EvaluatedCohort ret = new EvaluatedCohort(null, picd, context); if (ObjectUtil.notNull( picd.getRegexToMatch())) { // Query will return an array containing patientId and identifier for (Object o : results) { Object[] row = (Object[]) o; if (row.length == 2 && row[1] != null && row[1].toString().matches(picd.getRegexToMatch())) { ret.addMember((Integer) row[0]); } } } else { // Query returns only a patientId for (Object o : results) { ret.addMember((Integer) o); } } return ret; }
/** @see DataSetEvaluator#evaluate(DataSetDefinition, EvaluationContext) */ @SuppressWarnings("unchecked") public DataSet evaluate(DataSetDefinition dataSetDefinition, EvaluationContext context) throws EvaluationException { PatientDataSetDefinition dsd = (PatientDataSetDefinition) dataSetDefinition; context = ObjectUtil.nvl(context, new EvaluationContext()); SimpleDataSet dataSet = new SimpleDataSet(dsd, context); dataSet.setSortCriteria(dsd.getSortCriteria()); // Construct a new EvaluationContext based on the passed filters Cohort c = context.getBaseCohort(); if (dsd.getRowFilters() != null) { for (Mapped<? extends CohortDefinition> q : dsd.getRowFilters()) { Cohort s = Context.getService(CohortDefinitionService.class).evaluate(q, context); c = CohortUtil.intersectNonNull(c, s); } } if (c == null) { c = Context.getService(CohortDefinitionService.class) .evaluate(new AllPatientsCohortDefinition(), context); } EvaluationContext ec = context.shallowCopy(); if (!CohortUtil.areEqual(ec.getBaseCohort(), c)) { ec.setBaseCohort(c); } // Evaluate each specified ColumnDefinition for all of the included rows and add these to the // dataset for (RowPerObjectColumnDefinition cd : dsd.getColumnDefinitions()) { if (log.isDebugEnabled()) { log.debug("Evaluating column: " + cd.getName()); log.debug( "With Data Definition: " + DefinitionUtil.format(cd.getDataDefinition().getParameterizable())); log.debug("With Mappings: " + cd.getDataDefinition().getParameterMappings()); log.debug("With Parameters: " + ec.getParameterValues()); } StopWatch sw = new StopWatch(); sw.start(); MappedData<? extends PatientDataDefinition> dataDef = (MappedData<? extends PatientDataDefinition>) cd.getDataDefinition(); EvaluatedPatientData data = Context.getService(PatientDataService.class).evaluate(dataDef, ec); for (Integer id : c.getMemberIds()) { for (DataSetColumn column : cd.getDataSetColumns()) { Object val = data.getData().get(id); val = DataUtil.convertData(val, dataDef.getConverters()); dataSet.addColumnValue(id, column, val); } } sw.stop(); if (log.isDebugEnabled()) { log.debug("Evaluated column. Duration: " + sw.toString()); } } return dataSet; }
/** Adds in a Row to the given Sheet */ public Row addRow( Workbook wb, SheetToAdd sheetToAdd, RowToAdd rowToAdd, int rowIndex, ReportData reportData, ReportDesign design, Map<String, String> repeatSections) { // Create a new row and copy over style attributes from the row to add Row newRow = sheetToAdd.getSheet().createRow(rowIndex); Row rowToClone = rowToAdd.getRowToClone(); try { CellStyle rowStyle = rowToClone.getRowStyle(); if (rowStyle != null) { newRow.setRowStyle(rowStyle); } } catch (Exception e) { // No idea why this is necessary, but this has thrown IndexOutOfBounds errors getting the // rowStyle. Mysteries of POI } newRow.setHeight(rowToClone.getHeight()); // Iterate across all of the cells in the row, and configure all those that need to be // added/cloned List<CellToAdd> cellsToAdd = new ArrayList<CellToAdd>(); int totalCells = rowToClone.getPhysicalNumberOfCells(); int cellsFound = 0; for (int cellNum = 0; cellsFound < totalCells; cellNum++) { Cell currentCell = rowToClone.getCell(cellNum); log.debug("Handling cell: " + currentCell); if (currentCell != null) { cellsFound++; } // If we find that the cell that we are on is a repeating cell, then add the appropriate // number of cells to clone String repeatingColumnProperty = getRepeatingColumnProperty(sheetToAdd.getOriginalSheetNum(), cellNum, repeatSections); if (repeatingColumnProperty != null) { String[] dataSetSpanSplit = repeatingColumnProperty.split(","); String dataSetName = dataSetSpanSplit[0]; DataSet dataSet = getDataSet(reportData, dataSetName, rowToAdd.getReplacementData()); int numCellsToRepeat = 1; if (dataSetSpanSplit.length == 2) { numCellsToRepeat = Integer.parseInt(dataSetSpanSplit[1]); } log.debug( "Repeating this cell with dataset: " + dataSet + " and repeat of " + numCellsToRepeat); int repeatNum = 0; for (DataSetRow dataSetRow : dataSet) { repeatNum++; for (int i = 0; i < numCellsToRepeat; i++) { Cell cell = (i == 0 ? currentCell : rowToClone.getCell(cellNum + i)); if (repeatNum == 1 && cell != null && cell != currentCell) { cellsFound++; } Map<String, Object> newReplacements = getReplacementData( rowToAdd.getReplacementData(), reportData, design, dataSetName, dataSetRow, repeatNum); cellsToAdd.add(new CellToAdd(cell, newReplacements)); log.debug("Adding " + cell + " with dataSetRow: " + dataSetRow); } } cellNum += numCellsToRepeat; } else { cellsToAdd.add(new CellToAdd(currentCell, rowToAdd.getReplacementData())); log.debug("Adding " + currentCell); } } // Now, go through all of the collected cells, and add them back in ExcelStyleHelper styleHelper = new ExcelStyleHelper(wb); String prefix = getExpressionPrefix(design); String suffix = getExpressionSuffix(design); for (int i = 0; i < cellsToAdd.size(); i++) { CellToAdd cellToAdd = cellsToAdd.get(i); Cell newCell = newRow.createCell(i); Cell cellToClone = cellToAdd.getCellToClone(); if (cellToClone != null) { String contents = ExcelUtil.getCellContentsAsString(cellToClone); newCell.setCellStyle(cellToClone.getCellStyle()); try { newCell.setCellFormula(cellToClone.getCellFormula()); } catch (Exception e) { // Do nothing here. I don't know why POI throw exceptions here when the cell is not a // formula, but this suppresses them... } int numFormattings = sheetToAdd.getSheet().getSheetConditionalFormatting().getNumConditionalFormattings(); for (int n = 0; n < numFormattings; n++) { ConditionalFormatting f = sheetToAdd.getSheet().getSheetConditionalFormatting().getConditionalFormattingAt(n); for (CellRangeAddress add : f.getFormattingRanges()) { if (add.getFirstRow() == rowToAdd.getRowToClone().getRowNum() && add.getLastRow() == rowToClone.getRowNum()) { if (add.getFirstColumn() == cellToClone.getColumnIndex() && add.getLastColumn() == cellToClone.getColumnIndex()) { ConditionalFormattingRule[] rules = new ConditionalFormattingRule[f.getNumberOfRules()]; for (int j = 0; j < f.getNumberOfRules(); j++) { rules[j] = f.getRule(j); } CellRangeAddress[] cellRange = new CellRangeAddress[1]; cellRange[0] = new CellRangeAddress(rowIndex, rowIndex, i, i); sheetToAdd .getSheet() .getSheetConditionalFormatting() .addConditionalFormatting(cellRange, rules); } } } } if (ObjectUtil.notNull(contents)) { Object newContents = EvaluationUtil.evaluateExpression( contents, cellToAdd.getReplacementData(), prefix, suffix); ExcelUtil.setCellContents(styleHelper, newCell, newContents); } } } return newRow; }