use of org.openmrs.PersonAddress in project openmrs-core by openmrs.
the class PersonServiceTest method savePerson_shouldNotSetAVoidedNameOrAddressAsPreferred.
/**
* @see PersonService#savePerson(Person)
*/
@Test
public void savePerson_shouldNotSetAVoidedNameOrAddressAsPreferred() throws Exception {
Person person = new Person();
person.setGender("M");
PersonName name = new PersonName("givenName", "middleName", "familyName");
PersonName preferredName = new PersonName("givenName", "middleName", "familyName");
preferredName.setPreferred(true);
preferredName.setVoided(true);
person.addName(name);
person.addName(preferredName);
PersonAddress address = new PersonAddress();
address.setAddress1("some address");
PersonAddress preferredAddress = new PersonAddress();
preferredAddress.setAddress1("another address");
preferredAddress.setPreferred(true);
preferredAddress.setVoided(true);
person.addAddress(address);
person.addAddress(preferredAddress);
personService.savePerson(person);
Assert.assertFalse(preferredName.getPreferred());
Assert.assertFalse(preferredAddress.getPreferred());
assertTrue(name.getPreferred());
assertTrue(address.getPreferred());
}
use of org.openmrs.PersonAddress in project openmrs-module-pihcore by PIH.
the class WristbandTemplate method generateWristband.
public String generateWristband(Patient patient, Location location) {
// TODO figure out why this isn't getting autowired properly (at least for tests)
if (addressHierarchyService == null) {
addressHierarchyService = Context.getService(AddressHierarchyService.class);
}
StringBuffer data = new StringBuffer();
data.append("^XA");
// specify Unicode encoding
data.append("^CI28");
// set direct transfer type
data.append("^MTD");
// set orientation
data.append("^FWB");
// visit location & current data
data.append("^FO050,200^FB2150,1,0,L,0^AS^FD" + adtService.getLocationThatSupportsVisits(location).getName() + " " + fullDate.format(new Date()) + "^FS");
// patient name: for now, only printing given and family names
String patientName = null;
if (patient.getPersonName() != null) {
patientName = (patient.getPersonName().getGivenName() != null ? patient.getPersonName().getGivenName() : "") + " " + (patient.getPersonName().getFamilyName() != null ? patient.getPersonName().getFamilyName() : "");
}
data.append("^FO100,200^FB2150,1,0,L,0^AU^FD" + patientName + "^FS");
if (patient.getBirthdate() != null) {
// birthdate (we only show year if birthdate is estimated
DateFormat df = patient.getBirthdateEstimated() ? yearOnly : fullDate;
data.append("^FO160,200^FB2150,1,0,L,0^AU^FD" + df.format(patient.getBirthdate()) + "^FS");
}
if (patient.getAge() != null) {
// age
data.append("^FO160,200^FB1850,1,0,L,0^AT^FD" + messageSourceService.getMessage("coreapps.ageYears", Collections.singletonList(patient.getAge()).toArray(), locale) + "^FS");
}
// gender
data.append("^FO160,200^FB1650,1,0,L,0^AU^FD" + messageSourceService.getMessage("coreapps.gender." + patient.getGender(), null, locale) + " ");
// paper record identifier
PatientIdentifier paperRecordIdentifier = getAppropriatePaperRecordIdentifierForLocation(patient, location);
if (paperRecordIdentifier != null) {
data.append(paperRecordIdentifier.getIdentifier().substring(0, paperRecordIdentifier.getIdentifier().length() - 6) + " " + paperRecordIdentifier.getIdentifier().substring(paperRecordIdentifier.getIdentifier().length() - 6));
}
data.append("^FS");
// address (based on address hierarchy)
PersonAddress address = patient.getPersonAddress();
AddressHierarchyLevel level = addressHierarchyService.getBottomAddressHierarchyLevel();
int numberOfLevels = addressHierarchyService.getAddressHierarchyLevelsCount();
if (address != null && numberOfLevels > 0) {
int levelCount = 1;
if (LOWEST_LEVEL_ON_SEPARATE_LINE) {
String lowestLevelStr = AddressHierarchyUtil.getAddressFieldValue(address, level.getAddressField());
if (StringUtils.isNotBlank(address.getAddress2())) {
data.append("^FO220,200^FB2150,1,0,L,0^AS^FD" + lowestLevelStr + "^FS");
}
levelCount++;
}
StringBuffer addressStr = new StringBuffer();
while (levelCount < numberOfLevels || (!SKIP_HIGHEST_LEVEL && levelCount <= numberOfLevels) && level.getParent() != null) {
// level.getParent() should never equal null as long as levelCount <= numberOfLevels, but just to be safe we will check
level = level.getParent();
String levelStr = AddressHierarchyUtil.getAddressFieldValue(address, level.getAddressField());
if (StringUtils.isNotBlank(levelStr)) {
addressStr.append(levelStr + ", ");
}
levelCount++;
}
if (StringUtils.isNotBlank(addressStr.toString())) {
// trim off trailing comma and space
addressStr.delete(addressStr.length() - 2, addressStr.length());
data.append("^FO270,200^FB2150,1,0,L,0^AS^FD" + addressStr.toString() + "^FS");
}
}
// barcode with primary identifier
PatientIdentifier primaryIdentifier = patient.getPatientIdentifier(emrApiProperties.getPrimaryIdentifierType());
if (primaryIdentifier != null) {
data.append("^FO100,2400^AT^BY4^BC,150,N^FD" + primaryIdentifier.getIdentifier() + "^XZ");
}
return data.toString();
}
use of org.openmrs.PersonAddress in project openmrs-module-pihcore by PIH.
the class PihPatientSearchAlgorithmTest method exactAddressFieldMatchShouldIncreaseScore.
@Test
public void exactAddressFieldMatchShouldIncreaseScore() {
// first get the base score for this patient
Patient patient = new Patient();
PersonName name = new PersonName();
patient.addName(name);
name.setGivenName("Jarusz");
name.setFamilyName("Rapondee");
patient.setBirthdate(new Date());
patient.setGender("M");
List<PatientAndMatchQuality> results = searchAlgorithm.findSimilarPatients(patient, null, null, 10);
double scoreWithoutAddress = results.get(0).getScore();
// now add in address and recalculate
PersonAddress address = new PersonAddress();
address.setCityVillage("shiseso");
patient.addAddress(address);
results = searchAlgorithm.findSimilarPatients(patient, null, null, 10);
double scoreWithAddress = results.get(0).getScore();
// in our test config we've weighed cityVillage at 1 point
assertThat(scoreWithAddress - scoreWithoutAddress, is(1.0));
assertTrue(results.get(0).getMatchedFields().contains("addresses.cityVillage"));
}
use of org.openmrs.PersonAddress in project openmrs-module-pihcore by PIH.
the class PihPatientSearchAlgorithm method findSimilarPatients.
// TODO what about highlighting/showing the reasons for the match on the screen?
// TODO what about exact patient search algo? do we want to still use that, or just use this with a higher cutoff?
// TODO phonetics on attributes?
// TODO what about max results on initial query? needed?
// TODO more tests? make sure matchedfields are properly included?
// TODO address hierarchy field changes don't trigger a re-search
@Override
public List<PatientAndMatchQuality> findSimilarPatients(Patient patient, Map<String, Object> otherDataPoints, Double cutoff, Integer maxResults) {
// only do search if we have family name, given name, gender, and birthdate--return empty list otherwise
if (!hasName(patient) || !hasBirthdate(patient, otherDataPoints) || patient.getGender() == null) {
return new ArrayList<PatientAndMatchQuality>();
}
// our initial search to find a "base cohort"; hits will only occur if there is a phonetic match on both given name and family name
List<Patient> patients = getPatientsByPhonetics(patient.getGivenName(), patient.getFamilyName());
List<PatientAndMatchQuality> matches = new ArrayList<PatientAndMatchQuality>();
for (Patient match : patients) {
List<String> matchedFields = new ArrayList<String>();
double score = 0;
// these are matched by the fact that we made it through the name phonetics match
matchedFields.add("names.givenName");
matchedFields.add("names.familyName");
// one point if gender matches
if (patient.getGender() != null && match.getGender() != null) {
if (patient.getGender().equals(match.getGender())) {
score += 1;
matchedFields.add("gender");
} else {
score += -8;
}
}
// exact birthdate match = 10 pts; otherwise, if years between < 5, assign points based on 5-years between
if (patient.getBirthdate() != null && match.getBirthdate() != null) {
if (!match.getBirthdateEstimated() && new DateTime(patient.getBirthdate()).withTimeAtStartOfDay().equals(new DateTime(match.getBirthdate()).withTimeAtStartOfDay())) {
score += 10;
matchedFields.add("birthdate");
} else {
int yearsBetween = Math.abs(Years.yearsBetween(new DateTime(patient.getBirthdate()), new DateTime(match.getBirthdate())).getYears());
if (yearsBetween <= 5) {
score += (6 - yearsBetween);
matchedFields.add("birthdate");
} else {
score += -8;
}
}
} else // try estimated birthdate
{
Integer patientEstimatedAge = null;
if (otherDataPoints != null && otherDataPoints.containsKey("birthdateYears") && otherDataPoints.get("birthdateYears") != null) {
patientEstimatedAge = (Integer) otherDataPoints.get("birthdateYears");
} else if (otherDataPoints != null && otherDataPoints.containsKey("birthdateMonths") && otherDataPoints.get("birthdateMonths") != null) {
patientEstimatedAge = 0;
}
if (patientEstimatedAge != null) {
int yearsBetween = Math.abs(patientEstimatedAge - match.getAge());
if (yearsBetween < 5) {
score += (6 - yearsBetween);
matchedFields.add("birthdate");
}
}
}
// check for *exact* name matches
boolean familyNameMatch = false;
boolean givenNameMatch = false;
boolean middleNameMatch = false;
familyNameMatch = nameExactMatch(patient.getFamilyName(), match.getFamilyName());
givenNameMatch = nameExactMatch(patient.getGivenName(), match.getGivenName());
middleNameMatch = nameExactMatch(patient.getMiddleName(), match.getMiddleName());
if (familyNameMatch && givenNameMatch && middleNameMatch) {
score += 4;
} else if (familyNameMatch && givenNameMatch) {
score += 2;
} else if (familyNameMatch || givenNameMatch || middleNameMatch) {
score += 0.5;
}
// check for address matches
if (config.getRegistrationConfig() != null && config.getRegistrationConfig().getSimilarPatientsSearch() != null && config.getRegistrationConfig().getSimilarPatientsSearch().containsKey("addressFields")) {
Map<String, String> addressFields = (Map<String, String>) config.getRegistrationConfig().getSimilarPatientsSearch().get("addressFields");
PersonAddress patientAddress = patient.getPersonAddress();
PersonAddress matchAddress = match.getPersonAddress();
if (addressFields != null && patientAddress != null && matchAddress != null) {
for (String addressField : addressFields.keySet()) {
try {
String patientField = (String) PropertyUtils.getProperty(patientAddress, addressField);
String matchField = (String) PropertyUtils.getProperty(matchAddress, addressField);
if (StringUtils.isNotBlank(patientField) && StringUtils.isNotBlank(matchField) && stripAccentMarks(patientField).equalsIgnoreCase(stripAccentMarks(matchField))) {
score += new Double(addressFields.get(addressField));
matchedFields.add("addresses." + addressField);
}
} catch (Exception e) {
log.error("Unable to access " + addressField + " on patient during similar patient search");
}
}
}
}
// check person attribute matches
if (config.getRegistrationConfig() != null && config.getRegistrationConfig().getSimilarPatientsSearch() != null && config.getRegistrationConfig().getSimilarPatientsSearch().containsKey("personAttributeTypes")) {
Map<String, String> personAttributeTypes = (Map<String, String>) config.getRegistrationConfig().getSimilarPatientsSearch().get("personAttributeTypes");
for (String personAttributeType : personAttributeTypes.keySet()) {
String patientAttribute = patient.getAttribute(personAttributeType) != null ? patient.getAttribute(personAttributeType).getValue() : null;
String matchAttribute = match.getAttribute(personAttributeType) != null ? match.getAttribute(personAttributeType).getValue() : null;
if (StringUtils.isNotBlank(patientAttribute) && StringUtils.isNotBlank(matchAttribute)) {
// special case telephone number: strip all non-numerics
if (personAttributeType.equalsIgnoreCase(Metadata.getPhoneNumberAttributeType().getName())) {
patientAttribute = patientAttribute.replaceAll("[^0-9]", "");
matchAttribute = matchAttribute.replaceAll("[^0-9]", "");
}
// special case First Name of Mother: convert to name phonetics
if (personAttributeType.equalsIgnoreCase(Metadata.getMothersFirstNameAttributeType().getName())) {
patientAttribute = NamePhoneticsUtil.encodeString(patientAttribute, adminService.getGlobalProperty("namephonetics.givenNameStringEncoder"));
matchAttribute = NamePhoneticsUtil.encodeString(matchAttribute, adminService.getGlobalProperty("namephonetics.givenNameStringEncoder"));
}
if (stripAccentMarks(patientAttribute).equalsIgnoreCase(stripAccentMarks(matchAttribute))) {
score += new Double(personAttributeTypes.get(personAttributeType));
matchedFields.add("attributes." + personAttributeType);
}
}
}
}
// only take matches that make the cut
if (cutoff == null) {
matches.add(new PatientAndMatchQuality(match, score, matchedFields));
} else {
if (score >= cutoff) {
matches.add(new PatientAndMatchQuality(match, score, matchedFields));
}
}
}
Collections.sort(matches);
if (maxResults != null && matches.size() > maxResults) {
return matches.subList(0, maxResults);
} else {
return matches;
}
}
Aggregations