/** * give a expected xml string and make sure it can be shortly deserialized * * @throws Exception */ @Test public void shouldPersonShortDeserialization() throws Exception { // prepare the necessary data /* * Because "XXXShortConverter.unmarshal(HierarchicalStreamReader, UnmarshallingContext)" has operations accessing data in database, * We also need to use the "PersonShortSerializationTest.xml" here */ initializeInMemoryDatabase(); executeDataSet("org/openmrs/module/xstream/include/PersonShortSerializationTest.xml"); authenticate(); StringBuilder xmlBuilder = new StringBuilder(); xmlBuilder.append( "<personAddress id=\"1\" uuid=\"3350d0b5-821c-4e5e-ad1d-a9bce331e118\" voided=\"false\">\n"); xmlBuilder.append(" <creator id=\"2\" uuid=\"6adb7c42-cfd2-4301-b53b-ff17c5654ff7\"/>\n"); xmlBuilder.append( " <dateCreated class=\"sql-timestamp\" id=\"3\">2005-09-22 00:00:00 CST</dateCreated>\n"); xmlBuilder.append(" <personAddressId>2</personAddressId>\n"); xmlBuilder.append(" <person id=\"4\" uuid=\"da7f524f-27ce-4bb2-86d6-6d1d05312bd5\"/>\n"); xmlBuilder.append(" <preferred>false</preferred>\n"); xmlBuilder.append(" <address1>1050 Wishard Blvd.</address1>\n"); xmlBuilder.append(" <address2>RG5</address2>\n"); xmlBuilder.append(" <cityVillage>Indianapolis</cityVillage>\n"); xmlBuilder.append(" <stateProvince>IN</stateProvince>\n"); xmlBuilder.append(" <country>USA</country>\n"); xmlBuilder.append(" <postalCode>46202</postalCode>\n"); xmlBuilder.append("</personAddress>\n"); PersonAddress pa = Context.getSerializationService() .deserialize(xmlBuilder.toString(), PersonAddress.class, XStreamShortSerializer.class); assertEquals("da7f524f-27ce-4bb2-86d6-6d1d05312bd5", pa.getPerson().getUuid()); }
/** * Creates a non-persistent "Fake" Person (used when previewing or validating an HTML Form) * * @return the "fake" person */ public static Patient getFakePerson() { Patient demo = new Patient(); demo.addName(new PersonName("Demo", "The", "Person")); Location l = Context.getLocationService().getAllLocations().iterator().next(); for (PatientIdentifierType pit : Context.getPatientService().getAllPatientIdentifierTypes()) { if (StringUtils.isEmpty(pit.getValidator())) { demo.addIdentifier(new PatientIdentifier("Testing" + pit.getName() + "123", pit, l)); } } demo.setGender("F"); demo.setUuid("testing-html-form-entry"); { Calendar cal = Calendar.getInstance(); cal.add(Calendar.YEAR, -31); demo.setBirthdate(cal.getTime()); } for (PersonAttributeType type : Context.getPersonService().getAllPersonAttributeTypes()) { if (type.getFormat().equals("java.lang.String")) { demo.addAttribute(new PersonAttribute(type, "Test " + type.getName() + " Attribute")); } } PersonAddress addr = new PersonAddress(); addr.setCityVillage("Rwinkwavu"); addr.setCountyDistrict("Kayonza District"); addr.setStateProvince("Eastern Province"); addr.setCountry("Rwanda"); demo.addAddress(addr); return demo; }
/** * Compares this address to the given object/address for similarity. Uses the very basic * comparison of just the PersonAddress.personAddressId * * @param obj Object (Usually PersonAddress) with which to compare * @return boolean true/false whether or not they are the same objects * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { if (obj instanceof PersonAddress) { PersonAddress p = (PersonAddress) obj; if (this.getPersonAddressId() != null && p.getPersonAddressId() != null) return (this.getPersonAddressId().equals(p.getPersonAddressId())); } return false; }
/** @see ShortPatientFormValidator#validate(Object,Errors) */ @Test @Verifies(value = "should reject a duplicate address", method = "validate(Object,Errors)") public void validate_shouldRejectADuplicateAddress() throws Exception { Patient patient = ps.getPatient(2); PersonAddress oldAddress = patient.getPersonAddress(); Assert.assertEquals(1, patient.getAddresses().size()); // sanity check // add a name for testing purposes PersonAddress address = (PersonAddress) oldAddress.clone(); address.setPersonAddressId(null); address.setUuid(null); address.setAddress1("address1"); address.setAddress2("address2"); patient.addAddress(address); Context.getPatientService().savePatient(patient); Assert.assertNotNull(address.getId()); // should have been added ShortPatientModel model = new ShortPatientModel(patient); // should still be the preferred address for the test to pass Assert.assertEquals(oldAddress.getId(), model.getPersonAddress().getId()); // change to a duplicate name model.getPersonAddress().setAddress1("Address1"); // should be case insensitive model.getPersonAddress().setAddress2("address2"); Errors errors = new BindException(model, "patientModel"); validator.validate(model, errors); Assert.assertEquals(true, errors.hasErrors()); }
/** @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(PersonAddress other) { int retValue = 0; if (other != null) { retValue = isVoided().compareTo(other.isVoided()); if (retValue == 0) retValue = other.isPreferred().compareTo(isPreferred()); if (retValue == 0 && getDateCreated() != null) retValue = OpenmrsUtil.compareWithNullAsLatest(getDateCreated(), other.getDateCreated()); if (retValue == 0) retValue = OpenmrsUtil.compareWithNullAsGreatest(getPersonAddressId(), other.getPersonAddressId()); // if we've gotten this far, just check all address values. If they are // equal, leave the objects at 0. If not, arbitrarily pick retValue=1 // and return that (they are not equal). if (retValue == 0 && !equalsContent(other)) retValue = 1; } return retValue; }
/** * Auto generated method comment * * @param p * @param addressTypeId * @return */ public static String personAddress(Person p, Integer addressTypeId) { try { PersonAddress pa = null; if (p != null) pa = p.getPersonAddress(); if (pa != null) { switch (addressTypeId) { case 1: return (pa.getAddress1().compareToIgnoreCase("") == 0) ? "-" : pa.getAddress1(); case 2: return (pa.getAddress2().compareToIgnoreCase("") == 0) ? "-" : pa.getAddress2(); case 3: return (pa.getCityVillage().compareToIgnoreCase("") == 0) ? "-" : pa.getCityVillage(); default: return "-"; } } else return "-"; } catch (Exception e) { log.error(">>>>>>>>>>>>>>>>>>>VCT>>Module>>Tag>>>> An error occured : " + e.getMessage()); e.printStackTrace(); return "-"; } }
public static String getFullPersonAddress(Person p) { String address = "-/-/-/-/-/-"; try { // Country/Province/District/Sector/Cell/Umudugudu PersonAddress pa = null; if (p != null) pa = p.getPersonAddress(); if (pa != null) { address = ((pa.getCountry() != null) ? pa.getCountry() : "-") + " / " + ((pa.getStateProvince() != null) ? pa.getStateProvince() : "-") + " / " + ((pa.getCountyDistrict() != null) ? pa.getCountyDistrict() : "-") + " / " + ((pa.getCityVillage() != null) ? pa.getCityVillage() : "-") + " / " + ((pa.getNeighborhoodCell() != null) ? pa.getNeighborhoodCell() : "-") + " / " + ((pa.getAddress1() != null) ? pa.getAddress1() : "-"); } else return address; return address; } catch (Exception e) { log.error(">>>>>>>>>>>>>>>>>>>VCT>>Module>>Tag>>>> An error occured : " + e.getMessage()); e.printStackTrace(); return address; } }
/** * Validates the given Patient. * * @param obj The patient to validate. * @param errors The patient to validate. * @see org.springframework.validation.Validator#validate(java.lang.Object, * org.springframework.validation.Errors) * @should pass if the minimum required fields are provided and are valid * @should fail validation if gender is blank * @should fail validation if birthdate is blank * @should fail validation if birthdate makes patient 120 years old or older * @should fail validation if birthdate is a future date * @should fail validation if causeOfDeath is blank when patient is dead * @should fail if all name fields are empty or white space characters * @should fail if no identifiers are added * @should fail if all identifiers have been voided * @should fail if any name has more than 50 characters * @should fail validation if deathdate is a future date * @should fail if the deathdate is before the birthdate incase the patient is dead * @should reject a duplicate name * @should reject a duplicate address */ public void validate(Object obj, Errors errors) { if (log.isDebugEnabled()) { log.debug( this.getClass().getName() + ": Validating patient data from the short patient form...."); } ShortPatientModel shortPatientModel = (ShortPatientModel) obj; PersonName personName = shortPatientModel.getPersonName(); // TODO We should be able to let developers and implementations to specify which person name // fields should be used to determine uniqueness // check if this name has a unique givenName, middleName and familyName combination for (PersonName possibleDuplicate : shortPatientModel.getPatient().getNames()) { // don't compare the name to itself if (OpenmrsUtil.nullSafeEquals(possibleDuplicate.getId(), personName.getId())) { continue; } if (OpenmrsUtil.nullSafeEqualsIgnoreCase( possibleDuplicate.getGivenName(), personName.getGivenName()) && OpenmrsUtil.nullSafeEqualsIgnoreCase( possibleDuplicate.getMiddleName(), personName.getMiddleName()) && OpenmrsUtil.nullSafeEqualsIgnoreCase( possibleDuplicate.getFamilyName(), personName.getFamilyName())) { errors.reject( "Patient.duplicateName", new Object[] {personName.getFullName()}, personName.getFullName() + " is a duplicate name for the same patient"); } } Errors nameErrors = new BindException(personName, "personName"); new PersonNameValidator().validatePersonName(personName, nameErrors, false, true); if (nameErrors.hasErrors()) { // pick all the personName errors and bind them to the formObject Iterator<ObjectError> it = nameErrors.getAllErrors().iterator(); Set<String> errorCodesWithNoArguments = new HashSet<String>(); while (it.hasNext()) { ObjectError error = it.next(); // don't show similar error message multiple times in the view // unless they take in arguments which will make them atleast different if (error.getCode() != null && (!errorCodesWithNoArguments.contains(error.getCode()) || (error.getArguments() != null && error.getArguments().length > 0))) { errors.reject(error.getCode(), error.getArguments(), ""); if (error.getArguments() == null || error.getArguments().length == 0) { errorCodesWithNoArguments.add(error.getCode()); } } } // drop the collection errorCodesWithNoArguments = null; } // TODO We should be able to let developers and implementations to specify which // person address fields should be used to determine uniqueness // check if this address is unique PersonAddress personAddress = shortPatientModel.getPersonAddress(); for (PersonAddress possibleDuplicate : shortPatientModel.getPatient().getAddresses()) { // don't compare the address to itself if (OpenmrsUtil.nullSafeEquals(possibleDuplicate.getId(), personAddress.getId())) { continue; } if (!possibleDuplicate.isBlank() && !personAddress.isBlank() && possibleDuplicate.toString().equalsIgnoreCase(personAddress.toString())) { errors.reject( "Patient.duplicateAddress", new Object[] {personAddress.toString()}, personAddress.toString() + " is a duplicate address for the same patient"); } } if (CollectionUtils.isEmpty(shortPatientModel.getIdentifiers())) { errors.reject("PatientIdentifier.error.insufficientIdentifiers"); } else { boolean nonVoidedIdentifierFound = false; for (PatientIdentifier pId : shortPatientModel.getIdentifiers()) { // no need to validate unsaved identifiers that have been removed if (pId.getPatientIdentifierId() == null && pId.isVoided()) { continue; } if (!pId.isVoided()) { nonVoidedIdentifierFound = true; } new PatientIdentifierValidator().validate(pId, errors); } // if all the names are voided if (!nonVoidedIdentifierFound) { errors.reject("PatientIdentifier.error.insufficientIdentifiers"); } } // Make sure they chose a gender if (StringUtils.isBlank(shortPatientModel.getPatient().getGender())) { errors.rejectValue("patient.gender", "Person.gender.required"); } // check patients birthdate against future dates and really old dates if (shortPatientModel.getPatient().getBirthdate() != null) { if (shortPatientModel.getPatient().getBirthdate().after(new Date())) { errors.rejectValue("patient.birthdate", "error.date.future"); } else { Calendar c = Calendar.getInstance(); c.setTime(new Date()); c.add(Calendar.YEAR, -120); // patient cannot be older than 120 // years old if (shortPatientModel.getPatient().getBirthdate().before(c.getTime())) { errors.rejectValue("patient.birthdate", "error.date.nonsensical"); } } } else { errors.rejectValue( "patient.birthdate", "error.required", new Object[] {Context.getMessageSourceService().getMessage("Person.birthdate")}, ""); } // validate the personAddress if (shortPatientModel.getPersonAddress() != null) { try { errors.pushNestedPath("personAddress"); ValidationUtils.invokeValidator( new PersonAddressValidator(), shortPatientModel.getPersonAddress(), errors); } finally { errors.popNestedPath(); } } if (shortPatientModel.getPatient().getDead()) { if (shortPatientModel.getPatient().getCauseOfDeath() == null) { errors.rejectValue("patient.causeOfDeath", "Person.dead.causeOfDeathNull"); } if (shortPatientModel.getPatient().getDeathDate() != null) { if (shortPatientModel.getPatient().getDeathDate().after(new Date())) { errors.rejectValue("patient.deathDate", "error.date.future"); } // death date has to be after birthdate if both are specified if (shortPatientModel.getPatient().getBirthdate() != null && shortPatientModel .getPatient() .getDeathDate() .before(shortPatientModel.getPatient().getBirthdate())) { errors.rejectValue("patient.deathDate", "error.deathdate.before.birthdate"); } } } }
/** * @should void the old person address and replace it with a new one when it is edited * @should void the old person address and replace it with a new one when it is edited * @should not void the existing address if there are no changes */ public String post( UiSessionContext sessionContext, PageModel model, @RequestParam("patientId") @BindParams Patient patient, @BindParams PersonAddress address, @SpringBean("patientService") PatientService patientService, @RequestParam("appId") AppDescriptor app, @RequestParam("returnUrl") String returnUrl, @SpringBean("adminService") AdministrationService administrationService, HttpServletRequest request, @SpringBean("messageSourceService") MessageSourceService messageSourceService, Session session, @SpringBean("patientValidator") PatientValidator patientValidator, UiUtils ui) throws Exception { sessionContext.requireAuthentication(); if (patient.getPersonAddress() != null && address != null) { PersonAddress currentAddress = patient.getPersonAddress(); if (!currentAddress.equalsContent(address)) { // void the old address and replace it with the new one patient.addAddress(address); currentAddress.setVoided(true); } } NavigableFormStructure formStructure = RegisterPatientFormBuilder.buildFormStructure(app); BindingResult errors = new BeanPropertyBindingResult(patient, "patient"); patientValidator.validate(patient, errors); RegistrationAppUiUtils.validateLatitudeAndLongitudeIfNecessary(address, errors); if (formStructure != null) { RegisterPatientFormBuilder.resolvePersonAttributeFields( formStructure, patient, request.getParameterMap()); } if (!errors.hasErrors()) { try { // The person address changes get saved along as with the call to save patient patientService.savePatient(patient); InfoErrorMessageUtil.flashInfoMessage( request.getSession(), ui.message("registrationapp.editContactInfoMessage.success", patient.getPersonName())); return "redirect:" + returnUrl; } catch (Exception e) { log.warn("Error occurred while saving patient's contact info", e); session.setAttribute( UiCommonsConstants.SESSION_ATTRIBUTE_ERROR_MESSAGE, "registrationapp.save.fail"); } } else { model.addAttribute("errors", errors); StringBuffer errorMessage = new StringBuffer(messageSourceService.getMessage("error.failed.validation")); errorMessage.append("<ul>"); for (ObjectError error : errors.getAllErrors()) { errorMessage.append("<li>"); errorMessage.append( messageSourceService.getMessage( error.getCode(), error.getArguments(), error.getDefaultMessage(), null)); errorMessage.append("</li>"); } errorMessage.append("</ul>"); session.setAttribute( UiCommonsConstants.SESSION_ATTRIBUTE_ERROR_MESSAGE, errorMessage.toString()); } addModelAttributes(model, patient, formStructure, administrationService, returnUrl); // redisplay the form return null; }
@Test public void testWristBandTemplate() { Date today = new Date(); visitLocation.setName("Hôpital Universitaire de Mirebalais"); Patient patient = new Patient(); patient.setGender("M"); patient.setBirthdate(new DateTime(1940, 7, 7, 5, 5, 5).toDate()); PatientIdentifier primaryIdentifier = new PatientIdentifier(); primaryIdentifier.setIdentifier("ZL1234"); primaryIdentifier.setIdentifierType(primaryIdentifierType); primaryIdentifier.setVoided(false); patient.addIdentifier(primaryIdentifier); PatientIdentifier paperRecordIdentifier = new PatientIdentifier(); paperRecordIdentifier.setIdentifier("A000005"); paperRecordIdentifier.setIdentifierType(paperRecordIdentifierType); paperRecordIdentifier.setVoided(false); paperRecordIdentifier.setLocation(visitLocation); patient.addIdentifier(paperRecordIdentifier); PersonAddress address = new PersonAddress(); address.setAddress2("Avant Eglise Chretienne des perlerlerin de la siant tete de moliere"); address.setAddress1("Saut D'Eau"); address.setAddress3("1ere Riviere Canot"); address.setCityVillage("Saut d'Eau"); address.setStateProvince("Centre"); patient.addAddress(address); PersonName name = new PersonName(); name.setGivenName("Ringo"); name.setFamilyName("Starr"); patient.addName(name); when(messageSourceService.getMessage( "coreapps.ageYears", Collections.singletonList(patient.getAge()).toArray(), locale)) .thenReturn("75 an(s)"); String output = wristbandTemplate.generateWristband(patient, visitLocation); assertThat(output, containsString("^XA^CI28^MTD^FWB")); assertThat( output, containsString( "^FO050,200^FB2150,1,0,L,0^AS^FDHôpital Universitaire de Mirebalais " + df.format(today) + "^FS")); assertThat(output, containsString("^FO100,200^FB2150,1,0,L,0^AU^FDRingo Starr^FS")); assertThat(output, containsString("^FO160,200^FB2150,1,0,L,0^AU^FD07 juil. 1940^FS")); assertThat( output, containsString("^FO160,200^FB1850,1,0,L,0^AT^FD" + patient.getAge() + " an(s)^FS")); assertThat(output, containsString("^FO160,200^FB1650,1,0,L,0^AU^FDMasculin A 000005^FS")); assertThat( output, containsString( "^FO220,200^FB2150,1,0,L,0^AS^FDAvant Eglise Chretienne des perlerlerin de la siant tete de moliere^FS")); assertThat( output, containsString( "^FO270,200^FB2150,1,0,L,0^AS^FDSaut D'Eau, 1ere Riviere Canot, Saut d'Eau, Centre^FS")); assertThat(output, containsString("^FO100,2400^AT^BY4^BC,150,N^FDZL1234^XZ")); }