=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java 2014-01-07 19:37:58 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java 2014-01-22 04:25:46 +0000 @@ -44,348 +44,436 @@ * @version $Id$ */ -public interface PatientService -{ - String ID = PatientService.class.getName(); - - public static final int ERROR_NONE = 0; - - public static final int ERROR_DUPLICATE_IDENTIFIER = 1; - - public static final int ERROR_ENROLLMENT = 2; - - /** - * Adds an {@link Patient} - * - * @param patient The to Patient add. - * - * @return A generated unique id of the added {@link Patient}. - */ - int savePatient( Patient patient ); - - /** - * Deletes a {@link Patient}. - * - * @param patient the Patient to delete. - */ - void deletePatient( Patient patient ); - - /** - * Updates a {@link Patient}. - * - * @param patient the Patient to update. - */ - void updatePatient( Patient patient ); - - /** - * Returns a {@link Patient}. - * - * @param id the id of the PatientAttribute to return. - * - * @return the PatientAttribute with the given id - */ - Patient getPatient( int id ); - - /** - * Returns the {@link PatientAttribute} with the given UID. - * - * @param uid the UID. - * @return the PatientAttribute with the given UID, or null if no match. - */ - Patient getPatient( String uid ); - - /** - * Returns all {@link Patient} - * - * @return a collection of all Patient, or an empty collection if there are - * no Patients. - */ - Collection getAllPatients(); - - /** - * Retrieve patients for mobile base on identifier value - * - * @param searchText value - * @param orgUnitId - * - * @return Patient List - */ - Collection getPatientsForMobile( String searchText, int orgUnitId ); - - /** - * Retrieve patients base on organization unit with result limited - * - * @param organisationUnit organisationUnit - * @param min - * @param max - * - * @return Patient List - */ - Collection getPatients( OrganisationUnit organisationUnit, Integer min, Integer max ); - - /** - * Retrieve patients who enrolled into a program with active status - * - * @param program Program - * @return Patient list - */ - Collection getPatients( Program program ); - - /** - * Retrieve patients registered in a orgunit and enrolled into a program - * with active status - * - * @param organisationUnit - * @param program - * @return - */ - Collection getPatients( OrganisationUnit organisationUnit, Program program ); - - /** - * Retrieve patients base on PatientIdentifierType or Attribute or Patient's - * name - * - * @param identifierTypeId - * @param attributeId - * @param value - * @return - */ - Collection getPatient( Integer identifierTypeId, Integer attributeId, String value ); - - /** - * Search patients base on OrganisationUnit and Program with result limited - * name - * - * @param organisationUnit - * @param program - * @param min - * @param max - * @return - */ - Collection getPatients( OrganisationUnit organisationUnit, Program program, Integer min, Integer max ); - - /** - * Sort the result by PatientAttribute - * - * @param patients - * @param patientAttribute - * @return Patient List - */ - Collection sortPatientsByAttribute( Collection patients, PatientAttribute patientAttribute ); - - /** - * Get patients who has the same representative - * - * @params patient The representatives - * - * @return Patient List - * **/ - Collection getRepresentatives( Patient patient ); - - /** - * Register a new patient - * - * @param patient Patient - * @param representativeId The id of patient who is representative - * @param relationshipTypeId The id of relationship type defined - * @param attributeValues Set of attribute values - * - * @return The error code after registering patient - */ - int createPatient( Patient patient, Integer representativeId, Integer relationshipTypeId, - Set attributeValues ); - - /** - * Update information of an patient existed - * - * @param patient Patient - * @param representativeId The id of representative of this patient - * @param relationshipTypeId The id of relationship type of this person - * @param valuesForSave The patient attribute values for adding - * @param valuesForUpdate The patient attribute values for updating - * @param valuesForDelete The patient attribute values for deleting - * - */ - void updatePatient( Patient patient, Integer representativeId, Integer relationshipTypeId, - List valuesForSave, List valuesForUpdate, - Collection valuesForDelete ); - - /** - * Get the number of patients who registered into an organisation unit - * - * @param organisationUnit Organisation Unit - * - * @return The number of patients - */ - int countGetPatientsByOrgUnit( OrganisationUnit organisationUnit ); - - /** - * Get the number of patients who registered into an organisation unit and - * enrolled into a program - * - * @param organisationUnit Organisation Unit - * @param program Program - * - * @return The number of patients - */ - int countGetPatientsByOrgUnitProgram( OrganisationUnit organisationUnit, Program program ); - - /** - * Cache value from String to the value type based on property - * - * @param property Property name of patient - * @param value Value - * @param format I18nFormat - * - * @return An object - */ - Object getObjectValue( String property, String value, I18nFormat format ); - - /** - * Search patients by attribute values, identifiers and/or a program which - * patients enrolled into - * - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param patientAttributes The attribute values of these attribute are - * displayed into result - * @param identifierTypes The identifiers are displayed into the result - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * @param min - * @param max - * - * @return An object - */ - Collection searchPatients( List searchKeys, Collection orgunit, - Boolean followup, Collection patientAttributes, - Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ); - - /** - * Get the number of patients who meet the criteria for searching - * - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * - * @return The number of patients - */ - int countSearchPatients( List searchKeys, Collection orgunit, Boolean followup, - Integer statusEnrollment ); - - /** - * Get phone numbers of persons who meet the criteria for searching * - * - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * @param min - * @param max - * - * @return List of patient - */ - Collection getPatientPhoneNumbers( List searchKeys, Collection orgunit, - Boolean followup, Integer statusEnrollment, Integer min, Integer max ); - - /** - * Get events which meet the criteria for searching - * - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * @parma min - * @param max - * - * @return List of patient - */ - List getProgramStageInstances( List searchKeys, Collection orgunit, - Boolean followup, Integer statusEnrollment, Integer min, Integer max ); - - /** - * Get visit schedule of person who meet the criteria for searching - * - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * @parma min - * @param max - * - * @return Grid - */ - Grid getScheduledEventsReport( List searchKeys, Collection orgunits, Boolean followup, - Integer statusEnrollment, Integer min, Integer max, I18n i18n ); - - /** - * Search patients by phone number (performs partial search) - * - * @param phoneNumber The string for searching by phone number - * @param min - * @param max - * - * @return List of patient - */ - Collection getPatientsByPhone( String phoneNumber, Integer min, Integer max ); - - /** - * Get events of patients who meet the criteria for searching - * - * @param program Program. It's is used for getting identifier-types of this - * program and put identifiers of patients into the result - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * @param i18n I18n - * - * @return Grid - */ - Grid getTrackingEventsReport( Program program, List searchKeys, Collection orgunits, - Boolean followup, Integer statusEnrollment, I18n i18n ); - - /** - * Validate patient identifiers and validation criteria by program before - * registering or updating information - * - * @param patient Patient object - * @param program Program which person needs to enroll. If this parameter - * is null, the system check identifiers of the patient - * - * @return Error code 0 : Validation is OK 1 : The identifier is duplicated - * 2 : Violate validation criteria of the program - */ - int validatePatient( Patient patient, Program program ); +public interface PatientService { + String ID = PatientService.class.getName(); + + public static final int ERROR_NONE = 0; + + public static final int ERROR_DUPLICATE_IDENTIFIER = 1; + + public static final int ERROR_ENROLLMENT = 2; + + /** + * Adds an {@link Patient} + * + * @param patient + * The to Patient add. + * + * @return A generated unique id of the added {@link Patient}. + */ + int savePatient(Patient patient); + + /** + * Deletes a {@link Patient}. + * + * @param patient + * the Patient to delete. + */ + void deletePatient(Patient patient); + + /** + * Updates a {@link Patient}. + * + * @param patient + * the Patient to update. + */ + void updatePatient(Patient patient); + + /** + * Returns a {@link Patient}. + * + * @param id + * the id of the PatientAttribute to return. + * + * @return the PatientAttribute with the given id + */ + Patient getPatient(int id); + + /** + * Returns the {@link PatientAttribute} with the given UID. + * + * @param uid + * the UID. + * @return the PatientAttribute with the given UID, or null if no match. + */ + Patient getPatient(String uid); + + /** + * Returns all {@link Patient} + * + * @return a collection of all Patient, or an empty collection if there are + * no Patients. + */ + Collection getAllPatients(); + + /** + * Retrieve patients for mobile base on identifier value + * + * @param searchText + * value + * @param orgUnitId + * + * @return Patient List + */ + Collection getPatientsForMobile(String searchText, int orgUnitId); + + Collection searchPatientsForMobile(String searchText, + int orgUnitId, int patientAttributeId); + + /** + * Retrieve patients for mobile base on organization unit, patient attribute + * value + * + * @param searchText + * value + * @param patientAttributeId + * @param orgUnitId + * + * @return Patient List + */ + Collection getPatientsByAttributeValue(String searchText, + int patientAttributeId, Integer min, Integer max); + + /** + * Retrieve patients base on organization unit with result limited + * + * @param organisationUnit + * organisationUnit + * @param min + * @param max + * + * @return Patient List + */ + Collection getPatients(OrganisationUnit organisationUnit, + Integer min, Integer max); + + /** + * Retrieve patients who enrolled into a program with active status + * + * @param program + * Program + * @return Patient list + */ + Collection getPatients(Program program); + + /** + * Retrieve patients registered in a orgunit and enrolled into a program + * with active status + * + * @param organisationUnit + * @param program + * @return + */ + Collection getPatients(OrganisationUnit organisationUnit, + Program program); + + /** + * Retrieve patients base on PatientIdentifierType or Attribute or Patient's + * name + * + * @param identifierTypeId + * @param attributeId + * @param value + * @return + */ + Collection getPatient(Integer identifierTypeId, + Integer attributeId, String value); + + /** + * Search patients base on OrganisationUnit and Program with result limited + * name + * + * @param organisationUnit + * @param program + * @param min + * @param max + * @return + */ + Collection getPatients(OrganisationUnit organisationUnit, + Program program, Integer min, Integer max); + + /** + * Sort the result by PatientAttribute + * + * @param patients + * @param patientAttribute + * @return Patient List + */ + Collection sortPatientsByAttribute(Collection patients, + PatientAttribute patientAttribute); + + /** + * Get patients who has the same representative + * + * @params patient The representatives + * + * @return Patient List + * **/ + Collection getRepresentatives(Patient patient); + + /** + * Register a new patient + * + * @param patient + * Patient + * @param representativeId + * The id of patient who is representative + * @param relationshipTypeId + * The id of relationship type defined + * @param attributeValues + * Set of attribute values + * + * @return The error code after registering patient + */ + int createPatient(Patient patient, Integer representativeId, + Integer relationshipTypeId, + Set attributeValues); + + /** + * Update information of an patient existed + * + * @param patient + * Patient + * @param representativeId + * The id of representative of this patient + * @param relationshipTypeId + * The id of relationship type of this person + * @param valuesForSave + * The patient attribute values for adding + * @param valuesForUpdate + * The patient attribute values for updating + * @param valuesForDelete + * The patient attribute values for deleting + * + */ + void updatePatient(Patient patient, Integer representativeId, + Integer relationshipTypeId, + List valuesForSave, + List valuesForUpdate, + Collection valuesForDelete); + + /** + * Get the number of patients who registered into an organisation unit + * + * @param organisationUnit + * Organisation Unit + * + * @return The number of patients + */ + int countGetPatientsByOrgUnit(OrganisationUnit organisationUnit); + + /** + * Get the number of patients who registered into an organisation unit and + * enrolled into a program + * + * @param organisationUnit + * Organisation Unit + * @param program + * Program + * + * @return The number of patients + */ + int countGetPatientsByOrgUnitProgram(OrganisationUnit organisationUnit, + Program program); + + /** + * Cache value from String to the value type based on property + * + * @param property + * Property name of patient + * @param value + * Value + * @param format + * I18nFormat + * + * @return An object + */ + Object getObjectValue(String property, String value, I18nFormat format); + + /** + * Search patients by attribute values, identifiers and/or a program which + * patients enrolled into + * + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param patientAttributes + * The attribute values of these attribute are displayed into + * result + * @param identifierTypes + * The identifiers are displayed into the result + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * @param min + * @param max + * + * @return An object + */ + Collection searchPatients(List searchKeys, + Collection orgunit, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max); + + /** + * Get the number of patients who meet the criteria for searching + * + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * + * @return The number of patients + */ + int countSearchPatients(List searchKeys, + Collection orgunit, Boolean followup, + Integer statusEnrollment); + + /** + * Get phone numbers of persons who meet the criteria for searching * + * + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * @param min + * @param max + * + * @return List of patient + */ + Collection getPatientPhoneNumbers(List searchKeys, + Collection orgunit, Boolean followup, + Integer statusEnrollment, Integer min, Integer max); + + /** + * Get events which meet the criteria for searching + * + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * @parma min + * @param max + * + * @return List of patient + */ + List getProgramStageInstances(List searchKeys, + Collection orgunit, Boolean followup, + Integer statusEnrollment, Integer min, Integer max); + + /** + * Get visit schedule of person who meet the criteria for searching + * + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * @parma min + * @param max + * + * @return Grid + */ + Grid getScheduledEventsReport(List searchKeys, + Collection orgunits, Boolean followup, + Integer statusEnrollment, Integer min, Integer max, I18n i18n); + + /** + * Search patients by phone number (performs partial search) + * + * @param phoneNumber + * The string for searching by phone number + * @param min + * @param max + * + * @return List of patient + */ + Collection getPatientsByPhone(String phoneNumber, Integer min, + Integer max); + + /** + * Get events of patients who meet the criteria for searching + * + * @param program + * Program. It's is used for getting identifier-types of this + * program and put identifiers of patients into the result + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * @param i18n + * I18n + * + * @return Grid + */ + Grid getTrackingEventsReport(Program program, List searchKeys, + Collection orgunits, Boolean followup, + Integer statusEnrollment, I18n i18n); + + /** + * Validate patient identifiers and validation criteria by program before + * registering or updating information + * + * @param patient + * Patient object + * @param program + * Program which person needs to enroll. If this parameter is + * null, the system check identifiers of the patient + * + * @return Error code 0 : Validation is OK 1 : The identifier is duplicated + * 2 : Violate validation criteria of the program + */ + int validatePatient(Patient patient, Program program); } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java 2014-01-07 19:37:58 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java 2014-01-22 04:25:46 +0000 @@ -40,203 +40,261 @@ * @author Abyot Asalefew Gizaw * @version $Id$ */ -public interface PatientStore - extends GenericIdentifiableObjectStore -{ - final String ID = PatientStore.class.getName(); - - final int MAX_RESULTS = 50000; - - /** - * Search patients who registered in a certain organisation unit - * - * @param organisationUnit Organisation unit where patients registered - * @param min - * @param max - * - * @return List of patients - */ - Collection getByOrgUnit( OrganisationUnit organisationUnit, Integer min, Integer max ); - - /** - * Search patients registered into a certain organisation unit and enrolled - * into a program with active status - * - * @param organisationUnit Organisation unit where patients registered - * @param program Program. It's is used for getting identifier-types of this - * program and put identifiers of patients into the result - * @param min - * @param max - * - * @return List of patients - */ - Collection getByOrgUnitProgram( OrganisationUnit organisationUnit, Program program, Integer min, - Integer max ); - - List query( TrackedEntityQueryParams params ); - - /** - * Search patient who has the same representative - * - * @param patient Representative - * - * @return List of patients - */ - Collection getRepresentatives( Patient patient ); - - /** - * Search the number of patients who registered into an organisation unit - * - * @param organisationUnit Organisation unit - * - * @return The number of patients - */ - int countListPatientByOrgunit( OrganisationUnit organisationUnit ); - - /** - * Get the number of patients by full name (performs partial search ) - * - * @param name A string for searching by full name - * - * @return The number of patients - */ - int countGetPatientsByName( String name ); - - /** - * Get the number of patients who registered into a certain organisation - * unit and enrolled into a program with active status - * - * @param organisationUnit Organisation unit where patients registered - * @param program Program. It's is used for getting identifier-types of this - * program and put identifiers of patients into the result - * - * @return The number of patients - */ - int countGetPatientsByOrgUnitProgram( OrganisationUnit organisationUnit, Program program ); - - /** - * Get number of patients who meet the criteria for searching - * - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * - * @return The number of patients - */ - int countSearch( List searchKeys, Collection orgunit, Boolean followup, - Integer statusEnrollment ); - - /** - * Search patients by phone number (performs partial search) - * - * @param phoneNumber The string for searching by phone number - * @param min - * @param max - * - * @return List of patient - */ - Collection getByPhoneNumber( String phoneNumber, Integer min, Integer max ); - - /** - * Search events of patients who meet the criteria for searching - * - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param patientAttributes The attribute values of these attribute are - * displayed into result - * @param identifierTypes The identifiers are displayed into the result - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * @param min - * @param max - * - * @return List of patients - */ - Collection search( List searchKeys, Collection orgunit, Boolean followup, - Collection patientAttributes, Collection identifierTypes, - Integer statusEnrollment, Integer min, Integer max ); - - /** - * Search events which meet the criteria for searching - * - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param patientAttributes The attribute values of these attribute are - * displayed into result - * @param identifierTypes The identifiers are displayed into the result - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * @param min - * @param max - * - * @return List of patients - */ - List getProgramStageInstances( List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, - Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ); - - /** - * Search patients who enrolled into a program with active status - * - * @param program Program - * @param min - * @param max - * - * return List of patients - */ - Collection getByProgram( Program program, Integer min, Integer max ); - - /** - * Search events of patients who meet the criteria for searching - * - * @param grid Grid with headers - * @param searchKeys The key for searching patients by attribute values, - * identifiers and/or a program - * @param orgunit Organisation unit where patients registered - * @param followup Only getting patients with program risked if this - * property is true. And getting patients without program risked if - * its value is false - * @param patientAttributes The attribute values of these attribute are - * displayed into result - * @param identifierTypes The identifiers are displayed into the result - * @param statusEnrollment The status of program of patients. There are - * three status, includes Active enrollments only, Completed - * enrollments only and Active and completed enrollments - * @param min - * @param max - * - * @return Grid - */ - Grid getPatientEventReport( Grid grid, List searchKeys, Collection orgunit, - Boolean followup, Collection patientAttributes, - Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ); - - /** - * Validate patient identifiers and validation criteria by program before - * registering / updating information - * - * @param patient Patient object - * @param program Program which person needs to enroll. If this parameter - * is null, the system check identifiers of the patient - * - * @return Error code 0 : Validation is OK 1 : The identifier is duplicated - * 2 : Violate validation criteria of the program - */ - int validate( Patient patient, Program program ); +public interface PatientStore extends GenericIdentifiableObjectStore { + final String ID = PatientStore.class.getName(); + + final int MAX_RESULTS = 50000; + + /** + * Search patients who registered in a certain organisation unit + * + * @param organisationUnit + * Organisation unit where patients registered + * @param min + * @param max + * + * @return List of patients + */ + Collection getByOrgUnit(OrganisationUnit organisationUnit, + Integer min, Integer max); + + /** + * Search patients registered into a certain organisation unit and enrolled + * into a program with active status + * + * @param organisationUnit + * Organisation unit where patients registered + * @param program + * Program. It's is used for getting identifier-types of this + * program and put identifiers of patients into the result + * @param min + * @param max + * + * @return List of patients + */ + Collection getByOrgUnitProgram(OrganisationUnit organisationUnit, + Program program, Integer min, Integer max); + + List query(TrackedEntityQueryParams params); + + /** + * Search patient who has the same representative + * + * @param patient + * Representative + * + * @return List of patients + */ + Collection getRepresentatives(Patient patient); + + /** + * Search the number of patients who registered into an organisation unit + * + * @param organisationUnit + * Organisation unit + * + * @return The number of patients + */ + int countListPatientByOrgunit(OrganisationUnit organisationUnit); + + /** + * Get the number of patients by full name (performs partial search ) + * + * @param name + * A string for searching by full name + * + * @return The number of patients + */ + int countGetPatientsByName(String name); + + /** + * Get the number of patients who registered into a certain organisation + * unit and enrolled into a program with active status + * + * @param organisationUnit + * Organisation unit where patients registered + * @param program + * Program. It's is used for getting identifier-types of this + * program and put identifiers of patients into the result + * + * @return The number of patients + */ + int countGetPatientsByOrgUnitProgram(OrganisationUnit organisationUnit, + Program program); + + /** + * Get number of patients who meet the criteria for searching + * + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * + * @return The number of patients + */ + int countSearch(List searchKeys, + Collection orgunit, Boolean followup, + Integer statusEnrollment); + + /** + * Search patients by phone number (performs partial search) + * + * @param phoneNumber + * The string for searching by phone number + * @param min + * @param max + * + * @return List of patient + */ + + Collection getByPhoneNumber(String phoneNumber, Integer min, + Integer max); + + /** + * Search patients by attribute value (performs partial search) + * + * @param searchText + * The string for searching by attribute value + * @param patientAttributeId + * @param min + * @param max + * + * @return List of patient + */ + Collection getByPatientAttributeValue(String searchText, + int patientAttributeId, Integer min, Integer max); + + /** + * Search events of patients who meet the criteria for searching + * + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param patientAttributes + * The attribute values of these attribute are displayed into + * result + * @param identifierTypes + * The identifiers are displayed into the result + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * @param min + * @param max + * + * @return List of patients + */ + Collection search(List searchKeys, + Collection orgunit, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max); + + /** + * Search events which meet the criteria for searching + * + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param patientAttributes + * The attribute values of these attribute are displayed into + * result + * @param identifierTypes + * The identifiers are displayed into the result + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * @param min + * @param max + * + * @return List of patients + */ + List getProgramStageInstances(List searchKeys, + Collection orgunits, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max); + + /** + * Search patients who enrolled into a program with active status + * + * @param program + * Program + * @param min + * @param max + * + * return List of patients + */ + Collection getByProgram(Program program, Integer min, Integer max); + + /** + * Search events of patients who meet the criteria for searching + * + * @param grid + * Grid with headers + * @param searchKeys + * The key for searching patients by attribute values, + * identifiers and/or a program + * @param orgunit + * Organisation unit where patients registered + * @param followup + * Only getting patients with program risked if this property is + * true. And getting patients without program risked if its value + * is false + * @param patientAttributes + * The attribute values of these attribute are displayed into + * result + * @param identifierTypes + * The identifiers are displayed into the result + * @param statusEnrollment + * The status of program of patients. There are three status, + * includes Active enrollments only, Completed enrollments only + * and Active and completed enrollments + * @param min + * @param max + * + * @return Grid + */ + Grid getPatientEventReport(Grid grid, List searchKeys, + Collection orgunit, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max); + + /** + * Validate patient identifiers and validation criteria by program before + * registering / updating information + * + * @param patient + * Patient object + * @param program + * Program which person needs to enroll. If this parameter is + * null, the system check identifiers of the patient + * + * @return Error code 0 : Validation is OK 1 : The identifier is duplicated + * 2 : Violate validation criteria of the program + */ + int validate(Patient patient, Program program); } === modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientService.java' --- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientService.java 2014-01-09 15:34:25 +0000 +++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientService.java 2014-01-22 04:25:46 +0000 @@ -57,523 +57,521 @@ * @version $Id$ */ @Transactional -public class DefaultPatientService - implements PatientService -{ - // ------------------------------------------------------------------------- - // Dependencies - // ------------------------------------------------------------------------- - - private PatientStore patientStore; - - public void setPatientStore( PatientStore patientStore ) - { - this.patientStore = patientStore; - } - - private PatientIdentifierService patientIdentifierService; - - public void setPatientIdentifierService( PatientIdentifierService patientIdentifierService ) - { - this.patientIdentifierService = patientIdentifierService; - } - - private PatientAttributeValueService patientAttributeValueService; - - public void setPatientAttributeValueService( PatientAttributeValueService patientAttributeValueService ) - { - this.patientAttributeValueService = patientAttributeValueService; - } - - private PatientAttributeService patientAttributeService; - - public void setPatientAttributeService( PatientAttributeService patientAttributeService ) - { - this.patientAttributeService = patientAttributeService; - } - - private PatientIdentifierTypeService patientIdentifierTypeService; - - public void setPatientIdentifierTypeService( PatientIdentifierTypeService patientIdentifierTypeService ) - { - this.patientIdentifierTypeService = patientIdentifierTypeService; - } - - private RelationshipService relationshipService; - - public void setRelationshipService( RelationshipService relationshipService ) - { - this.relationshipService = relationshipService; - } - - private RelationshipTypeService relationshipTypeService; - - public void setRelationshipTypeService( RelationshipTypeService relationshipTypeService ) - { - this.relationshipTypeService = relationshipTypeService; - } - - // ------------------------------------------------------------------------- - // Implementation methods - // ------------------------------------------------------------------------- - - @Override - public int savePatient( Patient patient ) - { - return patientStore.save( patient ); - } - - @Override - public int createPatient( Patient patient, Integer representativeId, Integer relationshipTypeId, - Set patientAttributeValues ) - { - int id = savePatient( patient ); - - for ( PatientAttributeValue pav : patientAttributeValues ) - { - patientAttributeValueService.savePatientAttributeValue( pav ); - patient.getAttributeValues().add( pav ); - } - - // --------------------------------------------------------------------- - // If under age, save representative information - // --------------------------------------------------------------------- - - if ( representativeId != null ) - { - Patient representative = patientStore.get( representativeId ); - if ( representative != null ) - { - patient.setRepresentative( representative ); - - Relationship rel = new Relationship(); - rel.setPatientA( representative ); - rel.setPatientB( patient ); - - if ( relationshipTypeId != null ) - { - RelationshipType relType = relationshipTypeService.getRelationshipType( relationshipTypeId ); - if ( relType != null ) - { - rel.setRelationshipType( relType ); - relationshipService.saveRelationship( rel ); - } - } - } - } - - updatePatient( patient ); // Save patient to update associations - - return id; - } - - @Override - public void updatePatient( Patient patient ) - { - patientStore.update( patient ); - } - - @Override - public void deletePatient( Patient patient ) - { - patientStore.delete( patient ); - } - - @Override - public Patient getPatient( int id ) - { - return patientStore.get( id ); - } - - @Override - public Patient getPatient( String uid ) - { - return patientStore.getByUid( uid ); - } - - @Override - public Collection getAllPatients() - { - return patientStore.getAll(); - } - - @Override - public Collection getPatientsForMobile( String searchText, int orgUnitId ) - { - Set patients = new HashSet(); - patients.addAll( patientIdentifierService.getPatientsByIdentifier( searchText, 0, Integer.MAX_VALUE ) ); - patients.addAll( getPatientsByPhone( searchText, 0, Integer.MAX_VALUE ) ); - - // if an org-unit has been selected, filter out every patient that has a - // different org-unit - if ( orgUnitId != 0 ) - { - Set toRemoveList = new HashSet(); - - for ( Patient patient : patients ) - { - if ( patient.getOrganisationUnit().getId() != orgUnitId ) - { - toRemoveList.add( patient ); - } - } - - patients.removeAll( toRemoveList ); - } - - return patients; - } - - @Override - public Collection getPatients( OrganisationUnit organisationUnit, Integer min, Integer max ) - { - return patientStore.getByOrgUnit( organisationUnit, min, max ); - } - - @Override - public Collection getPatients( Program program ) - { - return patientStore.getByProgram( program, 0, Integer.MAX_VALUE ); - } - - @Override - public Collection getPatients( OrganisationUnit organisationUnit, Program program ) - { - return patientStore.getByOrgUnitProgram( organisationUnit, program, 0, Integer.MAX_VALUE ); - } - - @Override - public Collection getPatient( Integer identifierTypeId, Integer attributeId, String value ) - { - if ( attributeId != null ) - { - PatientAttribute attribute = patientAttributeService.getPatientAttribute( attributeId ); - if ( attribute != null ) - { - return patientAttributeValueService.getPatient( attribute, value ); - } - } - else if ( identifierTypeId != null ) - { - PatientIdentifierType identifierType = patientIdentifierTypeService - .getPatientIdentifierType( identifierTypeId ); - - if ( identifierType != null ) - { - Patient p = patientIdentifierService.getPatient( identifierType, value ); - if ( p != null ) - { - Set set = new HashSet(); - set.add( p ); - return set; - } - } - } - - return null; - } - - @Override - public Collection sortPatientsByAttribute( Collection patients, PatientAttribute patientAttribute ) - { - Collection sortedPatients = new ArrayList(); - - // --------------------------------------------------------------------- - // Better to fetch all attribute values at once than fetching the - // required attribute value of each patient using loop - // --------------------------------------------------------------------- - - Collection patientAttributeValues = patientAttributeValueService - .getPatientAttributeValues( patients ); - - if ( patientAttributeValues != null ) - { - for ( PatientAttributeValue patientAttributeValue : patientAttributeValues ) - { - if ( patientAttribute == patientAttributeValue.getPatientAttribute() ) - { - sortedPatients.add( patientAttributeValue.getPatient() ); - patients.remove( patientAttributeValue.getPatient() ); - } - } - } - - // --------------------------------------------------------------------- - // Make sure all patients are in the sorted list - because all - // patients might not have the sorting attribute/value - // --------------------------------------------------------------------- - - sortedPatients.addAll( patients ); - - return sortedPatients; - } - - @Override - public int countGetPatientsByOrgUnit( OrganisationUnit organisationUnit ) - { - return patientStore.countListPatientByOrgunit( organisationUnit ); - } - - @Override - public void updatePatient( Patient patient, Integer representativeId, Integer relationshipTypeId, - List valuesForSave, List valuesForUpdate, - Collection valuesForDelete ) - { - patientStore.update( patient ); - - for ( PatientAttributeValue av : valuesForSave ) - { - patientAttributeValueService.savePatientAttributeValue( av ); - } - - for ( PatientAttributeValue av : valuesForUpdate ) - { - patientAttributeValueService.updatePatientAttributeValue( av ); - } - - for ( PatientAttributeValue av : valuesForDelete ) - { - patientAttributeValueService.deletePatientAttributeValue( av ); - } - - if ( shouldSaveRepresentativeInformation( patient, representativeId ) ) - { - Patient representative = patientStore.get( representativeId ); - - if ( representative != null ) - { - patient.setRepresentative( representative ); - - Relationship rel = new Relationship(); - rel.setPatientA( representative ); - rel.setPatientB( patient ); - - if ( relationshipTypeId != null ) - { - RelationshipType relType = relationshipTypeService.getRelationshipType( relationshipTypeId ); - if ( relType != null ) - { - rel.setRelationshipType( relType ); - relationshipService.saveRelationship( rel ); - } - } - } - } - } - - private boolean shouldSaveRepresentativeInformation( Patient patient, Integer representativeId ) - { - if ( representativeId == null ) - { - return false; - } - - return patient.getRepresentative() == null || !(patient.getRepresentative().getId() == representativeId); - } - - @Override - public Collection getPatients( OrganisationUnit organisationUnit, Program program, Integer min, Integer max ) - { - return patientStore.getByOrgUnitProgram( organisationUnit, program, min, max ); - } - - @Override - public int countGetPatientsByOrgUnitProgram( OrganisationUnit organisationUnit, Program program ) - { - return patientStore.countGetPatientsByOrgUnitProgram( organisationUnit, program ); - } - - @Override - public Object getObjectValue( String property, String value, I18nFormat format ) - { - try - { - Type type = Patient.class.getMethod( "get" + StringUtils.capitalize( property ) ).getReturnType(); - - if ( type == Integer.class || type == Integer.TYPE ) - { - return Integer.valueOf( value ); - } - else if ( type.equals( Boolean.class ) || type == Boolean.TYPE ) - { - return Boolean.valueOf( value ); - } - else if ( type.equals( Date.class ) ) - { - return format.parseDate( value.trim() ); - } - else if ( type.equals( Character.class ) || type == Character.TYPE ) - { - return Character.valueOf( value.charAt( 0 ) ); - } - - return value; - } - catch ( Exception ex ) - { - ex.printStackTrace(); - } - - return null; - } - - @Override - public Collection getRepresentatives( Patient patient ) - { - return patientStore.getRepresentatives( patient ); - } - - @Override - public Collection searchPatients( List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, - Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ) - { - return patientStore.search( searchKeys, orgunits, followup, patientAttributes, identifierTypes, - statusEnrollment, min, max ); - } - - @Override - public int countSearchPatients( List searchKeys, Collection orgunits, Boolean followup, - Integer statusEnrollment ) - { - return patientStore.countSearch( searchKeys, orgunits, followup, statusEnrollment ); - } - - @Override - public Collection getPatientPhoneNumbers( List searchKeys, Collection orgunits, - Boolean followup, Integer statusEnrollment, Integer min, Integer max ) - { - Collection patients = patientStore.search( searchKeys, orgunits, followup, null, null, - statusEnrollment, min, max ); - Set phoneNumbers = new HashSet(); - - for ( Patient patient : patients ) - { - Collection attributeValues = patient.getAttributeValues(); - if ( attributeValues != null ) - { - for ( PatientAttributeValue attributeValue : attributeValues ) - { - if ( attributeValue.getPatientAttribute().getValueType() - .equals( PatientAttribute.TYPE_PHONE_NUMBER ) ) - { - phoneNumbers.add( attributeValue.getValue() ); - } - } - } - } - - return phoneNumbers; - } - - @Override - public List getProgramStageInstances( List searchKeys, Collection orgunits, - Boolean followup, Integer statusEnrollment, Integer min, Integer max ) - { - return patientStore.getProgramStageInstances( searchKeys, orgunits, followup, null, null, statusEnrollment, - min, max ); - } - - @Override - public Collection getPatientsByPhone( String phoneNumber, Integer min, Integer max ) - { - return patientStore.getByPhoneNumber( phoneNumber, min, max ); - } - - @Override - public Grid getScheduledEventsReport( List searchKeys, Collection orgunits, - Boolean followup, Integer statusEnrollment, Integer min, Integer max, I18n i18n ) - { - String startDate = ""; - String endDate = ""; - for ( String searchKey : searchKeys ) - { - String[] keys = searchKey.split( "_" ); - if ( keys[0].equals( Patient.PREFIX_PROGRAM_EVENT_BY_STATUS ) ) - { - startDate = keys[2]; - endDate = keys[3]; - } - } - - Grid grid = new ListGrid(); - grid.setTitle( i18n.getString( "activity_plan" ) ); - if ( !startDate.isEmpty() && !endDate.isEmpty() ) - { - grid.setSubtitle( i18n.getString( "from" ) + " " + startDate + " " + i18n.getString( "to" ) + " " + endDate ); - } - - grid.addHeader( new GridHeader( "patientid", true, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "first_name" ), false, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "middle_name" ), false, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "last_name" ), false, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "gender" ), false, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "phone_number" ), false, true ) ); - - Collection patientAttributes = patientAttributeService - .getPatientAttributesByDisplayOnVisitSchedule( true ); - for ( PatientAttribute patientAttribute : patientAttributes ) - { - grid.addHeader( new GridHeader( patientAttribute.getDisplayName(), false, true ) ); - } - - grid.addHeader( new GridHeader( "programstageinstanceid", true, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "program_stage" ), false, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "due_date" ), false, true ) ); - - return patientStore.getPatientEventReport( grid, searchKeys, orgunits, followup, patientAttributes, null, - statusEnrollment, min, max ); - } - - @Override - public Grid getTrackingEventsReport( Program program, List searchKeys, - Collection orgunits, Boolean followup, Integer statusEnrollment, I18n i18n ) - { - String startDate = ""; - String endDate = ""; - for ( String searchKey : searchKeys ) - { - String[] keys = searchKey.split( "_" ); - if ( keys[0].equals( Patient.PREFIX_PROGRAM_EVENT_BY_STATUS ) ) - { - startDate = keys[2]; - endDate = keys[3]; - } - } - - Grid grid = new ListGrid(); - grid.setTitle( i18n.getString( "program_tracking" ) ); - if ( !startDate.isEmpty() && !endDate.isEmpty() ) - { - grid.setSubtitle( i18n.getString( "from" ) + " " + startDate + " " + i18n.getString( "to" ) + " " + endDate ); - } - - grid.addHeader( new GridHeader( "patientid", true, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "first_name" ), true, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "middle_name" ), true, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "last_name" ), true, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "gender" ), true, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "phone_number" ), false, true ) ); - - Collection patientIdentifierTypes = program.getIdentifierTypes(); - - for ( PatientIdentifierType patientIdentifierType : patientIdentifierTypes ) - { - grid.addHeader( new GridHeader( patientIdentifierType.getDisplayName(), false, true ) ); - } - grid.addHeader( new GridHeader( "programstageinstanceid", true, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "program_stage" ), false, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "due_date" ), false, true ) ); - grid.addHeader( new GridHeader( i18n.getString( "risk" ), false, true ) ); - - return patientStore.getPatientEventReport( grid, searchKeys, orgunits, followup, null, patientIdentifierTypes, - statusEnrollment, null, null ); - } - - @Override - public int validatePatient( Patient patient, Program program ) - { - return patientStore.validate( patient, program ); - } +public class DefaultPatientService implements PatientService { + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + private PatientStore patientStore; + + public void setPatientStore(PatientStore patientStore) { + this.patientStore = patientStore; + } + + private PatientIdentifierService patientIdentifierService; + + public void setPatientIdentifierService( + PatientIdentifierService patientIdentifierService) { + this.patientIdentifierService = patientIdentifierService; + } + + private PatientAttributeValueService patientAttributeValueService; + + public void setPatientAttributeValueService( + PatientAttributeValueService patientAttributeValueService) { + this.patientAttributeValueService = patientAttributeValueService; + } + + private PatientAttributeService patientAttributeService; + + public void setPatientAttributeService( + PatientAttributeService patientAttributeService) { + this.patientAttributeService = patientAttributeService; + } + + private PatientIdentifierTypeService patientIdentifierTypeService; + + public void setPatientIdentifierTypeService( + PatientIdentifierTypeService patientIdentifierTypeService) { + this.patientIdentifierTypeService = patientIdentifierTypeService; + } + + private RelationshipService relationshipService; + + public void setRelationshipService(RelationshipService relationshipService) { + this.relationshipService = relationshipService; + } + + private RelationshipTypeService relationshipTypeService; + + public void setRelationshipTypeService( + RelationshipTypeService relationshipTypeService) { + this.relationshipTypeService = relationshipTypeService; + } + + // ------------------------------------------------------------------------- + // Implementation methods + // ------------------------------------------------------------------------- + + @Override + public int savePatient(Patient patient) { + return patientStore.save(patient); + } + + @Override + public int createPatient(Patient patient, Integer representativeId, + Integer relationshipTypeId, + Set patientAttributeValues) { + int id = savePatient(patient); + + for (PatientAttributeValue pav : patientAttributeValues) { + patientAttributeValueService.savePatientAttributeValue(pav); + patient.getAttributeValues().add(pav); + } + + // --------------------------------------------------------------------- + // If under age, save representative information + // --------------------------------------------------------------------- + + if (representativeId != null) { + Patient representative = patientStore.get(representativeId); + if (representative != null) { + patient.setRepresentative(representative); + + Relationship rel = new Relationship(); + rel.setPatientA(representative); + rel.setPatientB(patient); + + if (relationshipTypeId != null) { + RelationshipType relType = relationshipTypeService + .getRelationshipType(relationshipTypeId); + if (relType != null) { + rel.setRelationshipType(relType); + relationshipService.saveRelationship(rel); + } + } + } + } + + updatePatient(patient); // Save patient to update associations + + return id; + } + + @Override + public void updatePatient(Patient patient) { + patientStore.update(patient); + } + + @Override + public void deletePatient(Patient patient) { + patientStore.delete(patient); + } + + @Override + public Patient getPatient(int id) { + return patientStore.get(id); + } + + @Override + public Patient getPatient(String uid) { + return patientStore.getByUid(uid); + } + + @Override + public Collection getAllPatients() { + return patientStore.getAll(); + } + + @Override + public Collection getPatientsForMobile(String searchText, + int orgUnitId) { + Set patients = new HashSet(); + patients.addAll(getPatientsByPhone(searchText, 0, Integer.MAX_VALUE)); + patients.addAll(getPatientsByPhone(searchText, 0, Integer.MAX_VALUE)); + + // if an org-unit has been selected, filter out every patient that has a + // different org-unit + if (orgUnitId != 0) { + Set toRemoveList = new HashSet(); + + for (Patient patient : patients) { + if (patient.getOrganisationUnit().getId() != orgUnitId) { + toRemoveList.add(patient); + } + } + + patients.removeAll(toRemoveList); + } + + return patients; + } + + @Override + public Collection getPatients(OrganisationUnit organisationUnit, + Integer min, Integer max) { + return patientStore.getByOrgUnit(organisationUnit, min, max); + } + + @Override + public Collection getPatients(Program program) { + return patientStore.getByProgram(program, 0, Integer.MAX_VALUE); + } + + @Override + public Collection getPatients(OrganisationUnit organisationUnit, + Program program) { + return patientStore.getByOrgUnitProgram(organisationUnit, program, 0, + Integer.MAX_VALUE); + } + + @Override + public Collection getPatient(Integer identifierTypeId, + Integer attributeId, String value) { + if (attributeId != null) { + PatientAttribute attribute = patientAttributeService + .getPatientAttribute(attributeId); + if (attribute != null) { + return patientAttributeValueService + .getPatient(attribute, value); + } + } else if (identifierTypeId != null) { + PatientIdentifierType identifierType = patientIdentifierTypeService + .getPatientIdentifierType(identifierTypeId); + + if (identifierType != null) { + Patient p = patientIdentifierService.getPatient(identifierType, + value); + if (p != null) { + Set set = new HashSet(); + set.add(p); + return set; + } + } + } + + return null; + } + + @Override + public Collection sortPatientsByAttribute( + Collection patients, PatientAttribute patientAttribute) { + Collection sortedPatients = new ArrayList(); + + // --------------------------------------------------------------------- + // Better to fetch all attribute values at once than fetching the + // required attribute value of each patient using loop + // --------------------------------------------------------------------- + + Collection patientAttributeValues = patientAttributeValueService + .getPatientAttributeValues(patients); + + if (patientAttributeValues != null) { + for (PatientAttributeValue patientAttributeValue : patientAttributeValues) { + if (patientAttribute == patientAttributeValue + .getPatientAttribute()) { + sortedPatients.add(patientAttributeValue.getPatient()); + patients.remove(patientAttributeValue.getPatient()); + } + } + } + + // --------------------------------------------------------------------- + // Make sure all patients are in the sorted list - because all + // patients might not have the sorting attribute/value + // --------------------------------------------------------------------- + + sortedPatients.addAll(patients); + + return sortedPatients; + } + + @Override + public int countGetPatientsByOrgUnit(OrganisationUnit organisationUnit) { + return patientStore.countListPatientByOrgunit(organisationUnit); + } + + @Override + public void updatePatient(Patient patient, Integer representativeId, + Integer relationshipTypeId, + List valuesForSave, + List valuesForUpdate, + Collection valuesForDelete) { + patientStore.update(patient); + + for (PatientAttributeValue av : valuesForSave) { + patientAttributeValueService.savePatientAttributeValue(av); + } + + for (PatientAttributeValue av : valuesForUpdate) { + patientAttributeValueService.updatePatientAttributeValue(av); + } + + for (PatientAttributeValue av : valuesForDelete) { + patientAttributeValueService.deletePatientAttributeValue(av); + } + + if (shouldSaveRepresentativeInformation(patient, representativeId)) { + Patient representative = patientStore.get(representativeId); + + if (representative != null) { + patient.setRepresentative(representative); + + Relationship rel = new Relationship(); + rel.setPatientA(representative); + rel.setPatientB(patient); + + if (relationshipTypeId != null) { + RelationshipType relType = relationshipTypeService + .getRelationshipType(relationshipTypeId); + if (relType != null) { + rel.setRelationshipType(relType); + relationshipService.saveRelationship(rel); + } + } + } + } + } + + private boolean shouldSaveRepresentativeInformation(Patient patient, + Integer representativeId) { + if (representativeId == null) { + return false; + } + + return patient.getRepresentative() == null + || !(patient.getRepresentative().getId() == representativeId); + } + + @Override + public Collection getPatients(OrganisationUnit organisationUnit, + Program program, Integer min, Integer max) { + return patientStore.getByOrgUnitProgram(organisationUnit, program, min, + max); + } + + @Override + public int countGetPatientsByOrgUnitProgram( + OrganisationUnit organisationUnit, Program program) { + return patientStore.countGetPatientsByOrgUnitProgram(organisationUnit, + program); + } + + @Override + public Object getObjectValue(String property, String value, + I18nFormat format) { + try { + Type type = Patient.class.getMethod( + "get" + StringUtils.capitalize(property)).getReturnType(); + + if (type == Integer.class || type == Integer.TYPE) { + return Integer.valueOf(value); + } else if (type.equals(Boolean.class) || type == Boolean.TYPE) { + return Boolean.valueOf(value); + } else if (type.equals(Date.class)) { + return format.parseDate(value.trim()); + } else if (type.equals(Character.class) || type == Character.TYPE) { + return Character.valueOf(value.charAt(0)); + } + + return value; + } catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } + + @Override + public Collection getRepresentatives(Patient patient) { + return patientStore.getRepresentatives(patient); + } + + @Override + public Collection searchPatients(List searchKeys, + Collection orgunits, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max) { + return patientStore.search(searchKeys, orgunits, followup, + patientAttributes, identifierTypes, statusEnrollment, min, max); + } + + @Override + public int countSearchPatients(List searchKeys, + Collection orgunits, Boolean followup, + Integer statusEnrollment) { + return patientStore.countSearch(searchKeys, orgunits, followup, + statusEnrollment); + } + + @Override + public Collection getPatientPhoneNumbers(List searchKeys, + Collection orgunits, Boolean followup, + Integer statusEnrollment, Integer min, Integer max) { + Collection patients = patientStore.search(searchKeys, + orgunits, followup, null, null, statusEnrollment, min, max); + Set phoneNumbers = new HashSet(); + + for (Patient patient : patients) { + Collection attributeValues = patient + .getAttributeValues(); + if (attributeValues != null) { + for (PatientAttributeValue attributeValue : attributeValues) { + if (attributeValue.getPatientAttribute().getValueType() + .equals(PatientAttribute.TYPE_PHONE_NUMBER)) { + phoneNumbers.add(attributeValue.getValue()); + } + } + } + } + + return phoneNumbers; + } + + @Override + public List getProgramStageInstances(List searchKeys, + Collection orgunits, Boolean followup, + Integer statusEnrollment, Integer min, Integer max) { + return patientStore.getProgramStageInstances(searchKeys, orgunits, + followup, null, null, statusEnrollment, min, max); + } + + @Override + public Collection getPatientsByPhone(String phoneNumber, + Integer min, Integer max) { + return patientStore.getByPhoneNumber(phoneNumber, min, max); + } + + @Override + public Grid getScheduledEventsReport(List searchKeys, + Collection orgunits, Boolean followup, + Integer statusEnrollment, Integer min, Integer max, I18n i18n) { + String startDate = ""; + String endDate = ""; + for (String searchKey : searchKeys) { + String[] keys = searchKey.split("_"); + if (keys[0].equals(Patient.PREFIX_PROGRAM_EVENT_BY_STATUS)) { + startDate = keys[2]; + endDate = keys[3]; + } + } + + Grid grid = new ListGrid(); + grid.setTitle(i18n.getString("activity_plan")); + if (!startDate.isEmpty() && !endDate.isEmpty()) { + grid.setSubtitle(i18n.getString("from") + " " + startDate + " " + + i18n.getString("to") + " " + endDate); + } + + grid.addHeader(new GridHeader("patientid", true, true)); + grid.addHeader(new GridHeader(i18n.getString("first_name"), false, true)); + grid.addHeader(new GridHeader(i18n.getString("middle_name"), false, + true)); + grid.addHeader(new GridHeader(i18n.getString("last_name"), false, true)); + grid.addHeader(new GridHeader(i18n.getString("gender"), false, true)); + grid.addHeader(new GridHeader(i18n.getString("phone_number"), false, + true)); + + Collection patientAttributes = patientAttributeService + .getPatientAttributesByDisplayOnVisitSchedule(true); + for (PatientAttribute patientAttribute : patientAttributes) { + grid.addHeader(new GridHeader(patientAttribute.getDisplayName(), + false, true)); + } + + grid.addHeader(new GridHeader("programstageinstanceid", true, true)); + grid.addHeader(new GridHeader(i18n.getString("program_stage"), false, + true)); + grid.addHeader(new GridHeader(i18n.getString("due_date"), false, true)); + + return patientStore.getPatientEventReport(grid, searchKeys, orgunits, + followup, patientAttributes, null, statusEnrollment, min, max); + } + + @Override + public Grid getTrackingEventsReport(Program program, + List searchKeys, Collection orgunits, + Boolean followup, Integer statusEnrollment, I18n i18n) { + String startDate = ""; + String endDate = ""; + for (String searchKey : searchKeys) { + String[] keys = searchKey.split("_"); + if (keys[0].equals(Patient.PREFIX_PROGRAM_EVENT_BY_STATUS)) { + startDate = keys[2]; + endDate = keys[3]; + } + } + + Grid grid = new ListGrid(); + grid.setTitle(i18n.getString("program_tracking")); + if (!startDate.isEmpty() && !endDate.isEmpty()) { + grid.setSubtitle(i18n.getString("from") + " " + startDate + " " + + i18n.getString("to") + " " + endDate); + } + + grid.addHeader(new GridHeader("patientid", true, true)); + grid.addHeader(new GridHeader(i18n.getString("first_name"), true, true)); + grid.addHeader(new GridHeader(i18n.getString("middle_name"), true, true)); + grid.addHeader(new GridHeader(i18n.getString("last_name"), true, true)); + grid.addHeader(new GridHeader(i18n.getString("gender"), true, true)); + grid.addHeader(new GridHeader(i18n.getString("phone_number"), false, + true)); + + Collection patientIdentifierTypes = program + .getIdentifierTypes(); + + for (PatientIdentifierType patientIdentifierType : patientIdentifierTypes) { + grid.addHeader(new GridHeader(patientIdentifierType + .getDisplayName(), false, true)); + } + grid.addHeader(new GridHeader("programstageinstanceid", true, true)); + grid.addHeader(new GridHeader(i18n.getString("program_stage"), false, + true)); + grid.addHeader(new GridHeader(i18n.getString("due_date"), false, true)); + grid.addHeader(new GridHeader(i18n.getString("risk"), false, true)); + + return patientStore.getPatientEventReport(grid, searchKeys, orgunits, + followup, null, patientIdentifierTypes, statusEnrollment, null, + null); + } + + @Override + public int validatePatient(Patient patient, Program program) { + return patientStore.validate(patient, program); + } + + @Override + public Collection getPatientsByAttributeValue(String searchText, + int patientAttributeId, Integer min, Integer max) { + + return patientStore.getByPatientAttributeValue(searchText, + patientAttributeId, min, max); + } + + @Override + public Collection searchPatientsForMobile(String searchText, + int orgUnitId, int patientAttributeId) { + Set patients = new HashSet(); + + patients.addAll(getPatientsByAttributeValue(searchText, + patientAttributeId, 0, Integer.MAX_VALUE)); + + // if an org-unit has been selected, filter out every patient that has a + // different org-unit + if (orgUnitId != 0) { + Set toRemoveList = new HashSet(); + + for (Patient patient : patients) { + if (patient.getOrganisationUnit().getId() != orgUnitId) { + toRemoveList.add(patient); + } + } + + patients.removeAll(toRemoveList); + } + + return patients; + } } === modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientStore.java' --- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientStore.java 2014-01-05 14:04:13 +0000 +++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientStore.java 2014-01-22 04:25:46 +0000 @@ -63,6 +63,7 @@ import org.hisp.dhis.patient.PatientService; import org.hisp.dhis.patient.PatientStore; import org.hisp.dhis.patient.TrackedEntityQueryParams; +import org.hisp.dhis.patientattributevalue.PatientAttributeValue; import org.hisp.dhis.period.Period; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.ProgramInstance; @@ -79,732 +80,770 @@ * @author Abyot Asalefew Gizaw */ @Transactional -public class HibernatePatientStore - extends HibernateIdentifiableObjectStore - implements PatientStore -{ - private static final Log log = LogFactory.getLog( HibernatePatientStore.class ); - - // ------------------------------------------------------------------------- - // Dependencies - // ------------------------------------------------------------------------- - - private OrganisationUnitService organisationUnitService; - - public void setOrganisationUnitService( OrganisationUnitService organisationUnitService ) - { - this.organisationUnitService = organisationUnitService; - } - - // ------------------------------------------------------------------------- - // Implementation methods - // ------------------------------------------------------------------------- - - @Override - @SuppressWarnings( "unchecked" ) - public Collection getByOrgUnit( OrganisationUnit organisationUnit, Integer min, Integer max ) - { - String hql = "select p from Patient p where p.organisationUnit = :organisationUnit order by p.id DESC"; - - Query query = getQuery( hql ); - query.setEntity( "organisationUnit", organisationUnit ); - - if ( min != null && max != null ) - { - query.setFirstResult( min ).setMaxResults( max ); - } - - return query.list(); - } - - @Override - @SuppressWarnings( "unchecked" ) - public Collection getByOrgUnitProgram( OrganisationUnit organisationUnit, Program program, Integer min, - Integer max ) - { - String hql = "select pt from Patient pt inner join pt.programInstances pi " - + "where pt.organisationUnit = :organisationUnit " + "and pi.program = :program " - + "and pi.status = :status"; - - Query query = getQuery( hql ); - query.setEntity( "organisationUnit", organisationUnit ); - query.setEntity( "program", program ); - query.setInteger( "status", ProgramInstance.STATUS_ACTIVE ); - - return query.list(); - } - - @SuppressWarnings( "unchecked" ) - public List query( TrackedEntityQueryParams params ) - { - SqlHelper hlp = new SqlHelper(); - - String hql = "select pt from Patient pt left join pt.attributeValues av"; - - for ( QueryItem at : params.getAttributes() ) - { - hql += " " + hlp.whereAnd(); - hql += " (av.patientAttribute = :attr" + at.getItemId() + " and av.value = :filt" + at.getItemId() + ")"; - } - - Query query = getQuery( hql ); - - for ( QueryItem at : params.getAttributes() ) - { - query.setEntity( "attr" + at.getItemId(), at.getItem() ); - query.setString( "filt" + at.getItemId(), at.getFilter() ); - } - - return query.list(); - } - - @Override - @SuppressWarnings( "unchecked" ) - public Collection getByProgram( Program program, Integer min, Integer max ) - { - String hql = "select pt from Patient pt inner join pt.programInstances pi " - + "where pi.program = :program and pi.status = :status"; - - Query query = getQuery( hql ); - query.setEntity( "program", program ); - query.setInteger( "status", ProgramInstance.STATUS_ACTIVE ); - - return query.list(); - } - - @Override - public int countGetPatientsByName( String fullName ) - { - fullName = fullName.toLowerCase(); - String sql = "SELECT count(*) FROM patient where lower( name ) " + "like '%" + fullName + "%' "; - - return jdbcTemplate.queryForObject( sql, Integer.class ); - } - - @Override - public int countListPatientByOrgunit( OrganisationUnit organisationUnit ) - { - Query query = getQuery( "select count(p.id) from Patient p where p.organisationUnit.id=:orgUnitId " ); - - query.setParameter( "orgUnitId", organisationUnit.getId() ); - - Number rs = (Number) query.uniqueResult(); - - return rs != null ? rs.intValue() : 0; - } - - @Override - public int countGetPatientsByOrgUnitProgram( OrganisationUnit organisationUnit, Program program ) - { - String sql = "select count(p.patientid) from patient p join programinstance pi on p.patientid=pi.patientid " - + "where p.organisationunitid=" + organisationUnit.getId() + " and pi.programid=" + program.getId() - + " and pi.status=" + ProgramInstance.STATUS_ACTIVE; - - return jdbcTemplate.queryForObject( sql, Integer.class ); - } - - @Override - @SuppressWarnings( "unchecked" ) - public Collection getRepresentatives( Patient patient ) - { - String hql = "select distinct p from Patient p where p.representative = :representative order by p.id DESC"; - - return getQuery( hql ).setEntity( "representative", patient ).list(); - } - - @Override - // TODO this method must be changed - cannot retrieve one by one - public Collection search( List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, - Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ) - { - String sql = searchPatientSql( false, searchKeys, orgunits, followup, patientAttributes, identifierTypes, - statusEnrollment, min, max ); - Collection patients = new HashSet(); - try - { - patients = jdbcTemplate.query( sql, new RowMapper() - { - public Patient mapRow( ResultSet rs, int rowNum ) - throws SQLException - { - return get( rs.getInt( 1 ) ); - } - } ); - } - catch ( Exception ex ) - { - ex.printStackTrace(); - } - return patients; - } - - @Override - public List getProgramStageInstances( List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, - Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ) - { - String sql = searchPatientSql( false, searchKeys, orgunits, followup, patientAttributes, identifierTypes, - statusEnrollment, min, max ); - - List programStageInstanceIds = new ArrayList(); - try - { - programStageInstanceIds = jdbcTemplate.query( sql, new RowMapper() - { - public Integer mapRow( ResultSet rs, int rowNum ) - throws SQLException - { - return rs.getInt( "programstageinstanceid" ); - } - } ); - } - catch ( Exception ex ) - { - ex.printStackTrace(); - } - - return programStageInstanceIds; - } - - public int countSearch( List searchKeys, Collection orgunits, Boolean followup, - Integer statusEnrollment ) - { - String sql = searchPatientSql( true, searchKeys, orgunits, followup, null, null, statusEnrollment, null, null ); - return jdbcTemplate.queryForObject( sql, Integer.class ); - } - - @Override - public Grid getPatientEventReport( Grid grid, List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, - Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ) - { - String sql = searchPatientSql( false, searchKeys, orgunits, followup, patientAttributes, identifierTypes, - statusEnrollment, min, max ); - - SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql ); - - GridUtils.addRows( grid, rowSet ); - - return grid; - } - - @Override - @SuppressWarnings( "unchecked" ) - public Collection getByPhoneNumber( String phoneNumber, Integer min, Integer max ) - { - Criteria criteria = getCriteria(); - criteria.createAlias( "attributeValues", "attributeValue" ); - criteria.createAlias( "attributeValue.patientAttribute", "patientAttribute" ); - criteria.add( Restrictions.eq( "patientAttribute.valueType", PatientAttribute.TYPE_PHONE_NUMBER ) ); - criteria.add( Restrictions.like( "attributeValue.value", phoneNumber ) ); - - if ( min != null && max != null ) - { - criteria.setFirstResult( min ); - criteria.setMaxResults( max ); - } - - return criteria.list(); - } - - @SuppressWarnings( "unchecked" ) - public Collection getRegistrationOrgunitIds( Date startDate, Date endDate ) - { - Criteria criteria = getCriteria(); - criteria.add( Restrictions.between( "registrationDate", startDate, endDate ) ); - criteria.createAlias( "organisationUnit", "orgunit" ); - criteria.setProjection( Projections.distinct( Projections.projectionList().add( - Projections.property( "orgunit.id" ), "orgunitid" ) ) ); - - return criteria.list(); - } - - public int validate( Patient patient, Program program ) - { - if ( patient.getIdentifiers() != null && patient.getIdentifiers().size() > 0 ) - { - Criteria criteria = getCriteria(); - criteria.createAlias( "identifiers", "patientIdentifier" ); - criteria.createAlias( "organisationUnit", "orgunit" ); - criteria.createAlias( "programInstances", "programInstance" ); - criteria.createAlias( "programInstance.program", "program" ); - - Disjunction disjunction = Restrictions.disjunction(); - - for ( PatientIdentifier identifier : patient.getIdentifiers() ) - { - PatientIdentifierType patientIdentifierType = identifier.getIdentifierType(); - - Conjunction conjunction = Restrictions.conjunction(); - conjunction.add( Restrictions.eq( "patientIdentifier.identifier", identifier.getIdentifier() ) ); - conjunction.add( Restrictions.eq( "patientIdentifier.identifierType", patientIdentifierType ) ); - - if ( patient.getId() != 0 ) - { - conjunction.add( Restrictions.ne( "id", patient.getId() ) ); - } - - if ( patientIdentifierType.getType().equals( PatientIdentifierType.VALUE_TYPE_LOCAL_ID ) - && patientIdentifierType.getOrgunitScope() ) - { - conjunction.add( Restrictions.eq( "orgunit.id", patient.getOrganisationUnit().getId() ) ); - } - - if ( program != null - && patientIdentifierType.getType().equals( PatientIdentifierType.VALUE_TYPE_LOCAL_ID ) - && patientIdentifierType.getProgramScope() ) - { - conjunction.add( Restrictions.eq( "program", program ) ); - } - - if ( patientIdentifierType.getType().equals( PatientIdentifierType.VALUE_TYPE_LOCAL_ID ) - && patientIdentifierType.getPeriodType() != null ) - { - Date currentDate = new Date(); - Period period = patientIdentifierType.getPeriodType().createPeriod( currentDate ); - conjunction - .add( Restrictions.between( "enrollmentdate", period.getStartDate(), period.getEndDate() ) ); - } - - disjunction.add( conjunction ); - } - - criteria.add( disjunction ); - - Number rs = (Number) criteria.setProjection( Projections.rowCount() ).uniqueResult(); - - if ( rs != null && rs.intValue() > 0 ) - { - return PatientService.ERROR_DUPLICATE_IDENTIFIER; - } - } - - if ( program != null ) - { - ValidationCriteria validationCriteria = program.isValid( patient ); - - if ( validationCriteria != null ) - { - return PatientService.ERROR_ENROLLMENT; - } - } - - return PatientService.ERROR_NONE; - } - - // ------------------------------------------------------------------------- - // Supportive methods TODO Remplement all this! - // ------------------------------------------------------------------------- - - private String searchPatientSql( boolean count, List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, - Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ) - { - String selector = count ? "count(*) " : "* "; - String sql = "select " + selector + " from ( select distinct p.patientid,"; - - if ( identifierTypes != null ) - { - for ( PatientIdentifierType identifierType : identifierTypes ) - { - sql += "(select identifier from patientidentifier where patientid=p.patientid and patientidentifiertypeid=" - + identifierType.getId() + " ) as " + PREFIX_IDENTIFIER_TYPE + "_" + identifierType.getId() + " ,"; - } - } - - if ( patientAttributes != null ) - { - for ( PatientAttribute patientAttribute : patientAttributes ) - { - sql += "(select value from patientattributevalue where patientid=p.patientid and patientattributeid=" - + patientAttribute.getId() + " ) as " + PREFIX_PATIENT_ATTRIBUTE + "_" + patientAttribute.getId() - + " ,"; - } - } - - String patientWhere = ""; - String patientOperator = " where "; - String patientGroupBy = " GROUP BY p.patientid "; - String otherWhere = ""; - String operator = " where "; - String orderBy = ""; - boolean hasIdentifier = false; - boolean isSearchEvent = false; - boolean isPriorityEvent = false; - Collection orgunitChilrenIds = null; - - if ( orgunits != null ) - { - orgunitChilrenIds = getOrgunitChildren( orgunits ); - } - - for ( String searchKey : searchKeys ) - { - String[] keys = searchKey.split( "_" ); - - if ( keys.length <= 1 || keys[1] == null || keys[1].trim().isEmpty() || keys[1].equals( "null" ) ) - { - continue; - } - - String id = keys[1]; - String value = ""; - - if ( keys.length >= 3 ) - { - value = keys[2]; - } - - if ( keys[0].equals( PREFIX_IDENTIFIER_TYPE ) ) - { - - String[] keyValues = id.split( " " ); - patientWhere += patientOperator + " ("; - String opt = ""; - for ( String v : keyValues ) - { - patientWhere += opt + " ( lower(pi.identifier) like '%" + v - + "%' and pi.patientidentifiertypeid is not null ) "; - opt = "or"; - } - - patientWhere += ")"; - patientOperator = " and "; - hasIdentifier = true; - } - else if ( keys[0].equals( PREFIX_PATIENT_ATTRIBUTE ) ) - { - sql += "(select value from patientattributevalue where patientid=p.patientid and patientattributeid=" - + id + " ) as " + PREFIX_PATIENT_ATTRIBUTE + "_" + id + ","; - - String[] keyValues = value.split( " " ); - otherWhere += operator + "("; - String opt = ""; - - for ( String v : keyValues ) - { - otherWhere += opt + " lower(" + PREFIX_PATIENT_ATTRIBUTE + "_" + id + ") like '%" + v + "%'"; - opt = "or"; - } - - otherWhere += ")"; - operator = " and "; - } - else if ( keys[0].equals( PREFIX_PROGRAM ) ) - { - sql += "(select programid from programinstance pgi where patientid=p.patientid and programid=" + id; - - if ( statusEnrollment != null ) - { - sql += " and pgi.status=" + statusEnrollment; - } - - sql += " limit 1 ) as " + PREFIX_PROGRAM + "_" + id + ","; - otherWhere += operator + PREFIX_PROGRAM + "_" + id + "=" + id; - operator = " and "; - } - else if ( keys[0].equals( PREFIX_PROGRAM_INSTANCE ) ) - { - sql += "(select pi." + id + " from programinstance pi where patientid=p.patientid and pi.status=0 "; - - if ( keys.length == 5 ) - { - sql += " and pi.programid=" + keys[4]; - } - else - { - sql += " limit 1 "; - } - - sql += ") as " + PREFIX_PROGRAM_INSTANCE + "_" + id + ","; - otherWhere += operator + PREFIX_PROGRAM_INSTANCE + "_" + id + keys[2]; - operator = " and "; - } - else if ( keys[0].equals( PREFIX_PROGRAM_EVENT_BY_STATUS ) ) - { - isSearchEvent = true; - isPriorityEvent = Boolean.parseBoolean( keys[5] ); - patientWhere += patientOperator + "pgi.patientid=p.patientid and "; - patientWhere += "pgi.programid=" + id + " and "; - patientWhere += "pgi.status=" + ProgramInstance.STATUS_ACTIVE; - - String operatorStatus = ""; - String condition = " and ( "; - - for ( int index = 6; index < keys.length; index++ ) - { - int statusEvent = Integer.parseInt( keys[index] ); - switch ( statusEvent ) - { - case ProgramStageInstance.COMPLETED_STATUS: - patientWhere += condition + operatorStatus - + "( psi.executiondate is not null and psi.executiondate>='" + keys[2] - + "' and psi.executiondate<='" + keys[3] + "' and psi.completed=true "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and psi.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and psi.organisationunitid=" + getOrgUnitId( keys ); - } - - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - case ProgramStageInstance.VISITED_STATUS: - patientWhere += condition + operatorStatus - + "( psi.executiondate is not null and psi.executiondate>='" + keys[2] - + "' and psi.executiondate<='" + keys[3] + "' and psi.completed=false "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and psi.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and psi.organisationunitid=" + getOrgUnitId( keys ); - } - - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - case ProgramStageInstance.FUTURE_VISIT_STATUS: - patientWhere += condition + operatorStatus + "( psi.executiondate is null and psi.duedate>='" - + keys[2] + "' and psi.duedate<='" + keys[3] - + "' and psi.status is not null and (DATE(now()) - DATE(psi.duedate) <= 0) "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and p.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and p.organisationunitid=" + getOrgUnitId( keys ); - } - - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - case ProgramStageInstance.LATE_VISIT_STATUS: - patientWhere += condition + operatorStatus + "( psi.executiondate is null and psi.duedate>='" - + keys[2] + "' and psi.duedate<='" + keys[3] - + "' and psi.status is not null and (DATE(now()) - DATE(psi.duedate) > 0) "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and p.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and p.organisationunitid=" + getOrgUnitId( keys ); - } - - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - case ProgramStageInstance.SKIPPED_STATUS: - patientWhere += condition + operatorStatus + "( psi.status=5 and psi.duedate>='" + keys[2] - + "' and psi.duedate<='" + keys[3] + "' "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and psi.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and p.organisationunitid=" + getOrgUnitId( keys ); - } - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - default: - continue; - } - } - if ( condition.isEmpty() ) - { - patientWhere += ")"; - } - - patientWhere += " and pgi.status=" + ProgramInstance.STATUS_ACTIVE + " "; - patientOperator = " and "; - } - else if ( keys[0].equals( PREFIX_PROGRAM_STAGE ) ) - { - isSearchEvent = true; - patientWhere += patientOperator + "pgi.patientid=p.patientid and psi.programstageid=" + id + " and "; - patientWhere += "psi.duedate>='" + keys[3] + "' and psi.duedate<='" + keys[4] + "' and "; - patientWhere += "psi.organisationunitid = " + keys[5] + " and "; - - int statusEvent = Integer.parseInt( keys[2] ); - switch ( statusEvent ) - { - case ProgramStageInstance.COMPLETED_STATUS: - patientWhere += "psi.completed=true"; - break; - case ProgramStageInstance.VISITED_STATUS: - patientWhere += "psi.executiondate is not null and psi.completed=false"; - break; - case ProgramStageInstance.FUTURE_VISIT_STATUS: - patientWhere += "psi.executiondate is null and psi.duedate >= now()"; - break; - case ProgramStageInstance.LATE_VISIT_STATUS: - patientWhere += "psi.executiondate is null and psi.duedate < now()"; - break; - default: - break; - } - - patientWhere += " and pgi.status=" + ProgramInstance.STATUS_ACTIVE + " "; - patientOperator = " and "; - } - } - - if ( orgunits != null && !isSearchEvent ) - { - sql += "(select organisationunitid from patient where patientid=p.patientid and organisationunitid in ( " - + TextUtils.getCommaDelimitedString( getOrganisationUnitIds( orgunits ) ) + " ) ) as orgunitid,"; - otherWhere += operator + "orgunitid in ( " - + TextUtils.getCommaDelimitedString( getOrganisationUnitIds( orgunits ) ) + " ) "; - } - - sql = sql.substring( 0, sql.length() - 1 ) + " "; // Removing last comma - - String from = " from patient p "; - - if ( isSearchEvent ) - { - String subSQL = " , psi.programstageinstanceid as programstageinstanceid, pgs.name as programstagename, psi.duedate as duedate "; - - if ( isPriorityEvent ) - { - subSQL += ",pgi.followup "; - orderBy = " ORDER BY pgi.followup desc, p.patientid, duedate asc "; - patientGroupBy += ",pgi.followup "; - } - else - { - orderBy = " ORDER BY p.patientid, duedate asc "; - } - - sql = sql + subSQL + from + " inner join programinstance pgi on " + " (pgi.patientid=p.patientid) " - + " inner join programstageinstance psi on (psi.programinstanceid=pgi.programinstanceid) " - + " inner join programstage pgs on (pgs.programstageid=psi.programstageid) "; - - patientGroupBy += ",psi.programstageinstanceid, pgs.name, psi.duedate "; - - from = " "; - } - - if ( hasIdentifier ) - { - sql += from + " left join patientidentifier pi on p.patientid=pi.patientid "; - from = " "; - } - - sql += from + patientWhere; - if ( followup != null ) - { - sql += " AND pgi.followup=" + followup; - } - if ( isSearchEvent ) - { - sql += patientGroupBy; - } - sql += orderBy; - sql += " ) as searchresult"; - sql += otherWhere; - - if ( min != null && max != null ) - { - sql += " limit " + max + " offset " + min; - } - - log.info( "Search patient SQL: " + sql ); - - return sql; - } - - private Integer getOrgUnitId( String[] keys ) - { - Integer orgUnitId; - try - { - orgUnitId = Integer.parseInt( keys[4] ); - } - catch ( NumberFormatException e ) - { - // handle as uid - OrganisationUnit ou = organisationUnitService.getOrganisationUnit( keys[4] ); - orgUnitId = ou.getId(); - } - return orgUnitId; - } - - private Collection getOrgunitChildren( Collection orgunits ) - { - Collection orgUnitIds = new HashSet(); - - if ( orgunits != null ) - { - for ( OrganisationUnit orgunit : orgunits ) - { - orgUnitIds - .addAll( organisationUnitService.getOrganisationUnitHierarchy().getChildren( orgunit.getId() ) ); - orgUnitIds.remove( orgunit.getId() ); - } - } - - if ( orgUnitIds.size() == 0 ) - { - orgUnitIds.add( 0 ); - } - - return orgUnitIds; - } - - private Collection getOrganisationUnitIds( Collection orgunits ) - { - Collection orgUnitIds = new HashSet(); - - for ( OrganisationUnit orgUnit : orgunits ) - { - orgUnitIds.add( orgUnit.getId() ); - } - - if ( orgUnitIds.size() == 0 ) - { - orgUnitIds.add( 0 ); - } - - return orgUnitIds; - } +public class HibernatePatientStore extends + HibernateIdentifiableObjectStore implements PatientStore { + private static final Log log = LogFactory + .getLog(HibernatePatientStore.class); + + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + private OrganisationUnitService organisationUnitService; + + public void setOrganisationUnitService( + OrganisationUnitService organisationUnitService) { + this.organisationUnitService = organisationUnitService; + } + + // ------------------------------------------------------------------------- + // Implementation methods + // ------------------------------------------------------------------------- + + @Override + @SuppressWarnings("unchecked") + public Collection getByOrgUnit(OrganisationUnit organisationUnit, + Integer min, Integer max) { + String hql = "select p from Patient p where p.organisationUnit = :organisationUnit order by p.id DESC"; + + Query query = getQuery(hql); + query.setEntity("organisationUnit", organisationUnit); + + if (min != null && max != null) { + query.setFirstResult(min).setMaxResults(max); + } + + return query.list(); + } + + @Override + @SuppressWarnings("unchecked") + public Collection getByOrgUnitProgram( + OrganisationUnit organisationUnit, Program program, Integer min, + Integer max) { + String hql = "select pt from Patient pt inner join pt.programInstances pi " + + "where pt.organisationUnit = :organisationUnit " + + "and pi.program = :program " + "and pi.status = :status"; + + Query query = getQuery(hql); + query.setEntity("organisationUnit", organisationUnit); + query.setEntity("program", program); + query.setInteger("status", ProgramInstance.STATUS_ACTIVE); + + return query.list(); + } + + @SuppressWarnings("unchecked") + public List query(TrackedEntityQueryParams params) { + SqlHelper hlp = new SqlHelper(); + + String hql = "select pt from Patient pt left join pt.attributeValues av"; + + for (QueryItem at : params.getAttributes()) { + hql += " " + hlp.whereAnd(); + hql += " (av.patientAttribute = :attr" + at.getItemId() + + " and av.value = :filt" + at.getItemId() + ")"; + } + + Query query = getQuery(hql); + + for (QueryItem at : params.getAttributes()) { + query.setEntity("attr" + at.getItemId(), at.getItem()); + query.setString("filt" + at.getItemId(), at.getFilter()); + } + + return query.list(); + } + + @Override + @SuppressWarnings("unchecked") + public Collection getByProgram(Program program, Integer min, + Integer max) { + String hql = "select pt from Patient pt inner join pt.programInstances pi " + + "where pi.program = :program and pi.status = :status"; + + Query query = getQuery(hql); + query.setEntity("program", program); + query.setInteger("status", ProgramInstance.STATUS_ACTIVE); + + return query.list(); + } + + @Override + public int countGetPatientsByName(String fullName) { + fullName = fullName.toLowerCase(); + String sql = "SELECT count(*) FROM patient where lower( name ) " + + "like '%" + fullName + "%' "; + + return jdbcTemplate.queryForObject(sql, Integer.class); + } + + @Override + public int countListPatientByOrgunit(OrganisationUnit organisationUnit) { + Query query = getQuery("select count(p.id) from Patient p where p.organisationUnit.id=:orgUnitId "); + + query.setParameter("orgUnitId", organisationUnit.getId()); + + Number rs = (Number) query.uniqueResult(); + + return rs != null ? rs.intValue() : 0; + } + + @Override + public int countGetPatientsByOrgUnitProgram( + OrganisationUnit organisationUnit, Program program) { + String sql = "select count(p.patientid) from patient p join programinstance pi on p.patientid=pi.patientid " + + "where p.organisationunitid=" + + organisationUnit.getId() + + " and pi.programid=" + + program.getId() + + " and pi.status=" + + ProgramInstance.STATUS_ACTIVE; + + return jdbcTemplate.queryForObject(sql, Integer.class); + } + + @Override + @SuppressWarnings("unchecked") + public Collection getRepresentatives(Patient patient) { + String hql = "select distinct p from Patient p where p.representative = :representative order by p.id DESC"; + + return getQuery(hql).setEntity("representative", patient).list(); + } + + @Override + // TODO this method must be changed - cannot retrieve one by one + public Collection search(List searchKeys, + Collection orgunits, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max) { + String sql = searchPatientSql(false, searchKeys, orgunits, followup, + patientAttributes, identifierTypes, statusEnrollment, min, max); + Collection patients = new HashSet(); + try { + patients = jdbcTemplate.query(sql, new RowMapper() { + public Patient mapRow(ResultSet rs, int rowNum) + throws SQLException { + return get(rs.getInt(1)); + } + }); + } catch (Exception ex) { + ex.printStackTrace(); + } + return patients; + } + + @Override + public List getProgramStageInstances(List searchKeys, + Collection orgunits, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max) { + String sql = searchPatientSql(false, searchKeys, orgunits, followup, + patientAttributes, identifierTypes, statusEnrollment, min, max); + + List programStageInstanceIds = new ArrayList(); + try { + programStageInstanceIds = jdbcTemplate.query(sql, + new RowMapper() { + public Integer mapRow(ResultSet rs, int rowNum) + throws SQLException { + return rs.getInt("programstageinstanceid"); + } + }); + } catch (Exception ex) { + ex.printStackTrace(); + } + + return programStageInstanceIds; + } + + public int countSearch(List searchKeys, + Collection orgunits, Boolean followup, + Integer statusEnrollment) { + String sql = searchPatientSql(true, searchKeys, orgunits, followup, + null, null, statusEnrollment, null, null); + return jdbcTemplate.queryForObject(sql, Integer.class); + } + + @Override + public Grid getPatientEventReport(Grid grid, List searchKeys, + Collection orgunits, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max) { + String sql = searchPatientSql(false, searchKeys, orgunits, followup, + patientAttributes, identifierTypes, statusEnrollment, min, max); + + SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql); + + GridUtils.addRows(grid, rowSet); + + return grid; + } + + @Override + @SuppressWarnings("unchecked") + public Collection getByPhoneNumber(String phoneNumber, + Integer min, Integer max) { + Criteria criteria = getCriteria(); + criteria.createAlias("attributeValues", "attributeValue"); + criteria.createAlias("attributeValue.patientAttribute", + "patientAttribute"); + criteria.add(Restrictions.eq("patientAttribute.valueType", + PatientAttribute.TYPE_PHONE_NUMBER)); + criteria.add(Restrictions.like("attributeValue.value", phoneNumber)); + + if (min != null && max != null) { + criteria.setFirstResult(min); + criteria.setMaxResults(max); + } + + return criteria.list(); + } + + @SuppressWarnings("unchecked") + public Collection getRegistrationOrgunitIds(Date startDate, + Date endDate) { + Criteria criteria = getCriteria(); + criteria.add(Restrictions.between("registrationDate", startDate, + endDate)); + criteria.createAlias("organisationUnit", "orgunit"); + criteria.setProjection(Projections.distinct(Projections + .projectionList().add(Projections.property("orgunit.id"), + "orgunitid"))); + + return criteria.list(); + } + + public int validate(Patient patient, Program program) { + if (patient.getIdentifiers() != null + && patient.getIdentifiers().size() > 0) { + Criteria criteria = getCriteria(); + criteria.createAlias("identifiers", "patientIdentifier"); + criteria.createAlias("organisationUnit", "orgunit"); + criteria.createAlias("programInstances", "programInstance"); + criteria.createAlias("programInstance.program", "program"); + + Disjunction disjunction = Restrictions.disjunction(); + + for (PatientIdentifier identifier : patient.getIdentifiers()) { + PatientIdentifierType patientIdentifierType = identifier + .getIdentifierType(); + + Conjunction conjunction = Restrictions.conjunction(); + conjunction.add(Restrictions.eq("patientIdentifier.identifier", + identifier.getIdentifier())); + conjunction.add(Restrictions.eq( + "patientIdentifier.identifierType", + patientIdentifierType)); + + if (patient.getId() != 0) { + conjunction.add(Restrictions.ne("id", patient.getId())); + } + + if (patientIdentifierType.getType().equals( + PatientIdentifierType.VALUE_TYPE_LOCAL_ID) + && patientIdentifierType.getOrgunitScope()) { + conjunction.add(Restrictions.eq("orgunit.id", patient + .getOrganisationUnit().getId())); + } + + if (program != null + && patientIdentifierType.getType().equals( + PatientIdentifierType.VALUE_TYPE_LOCAL_ID) + && patientIdentifierType.getProgramScope()) { + conjunction.add(Restrictions.eq("program", program)); + } + + if (patientIdentifierType.getType().equals( + PatientIdentifierType.VALUE_TYPE_LOCAL_ID) + && patientIdentifierType.getPeriodType() != null) { + Date currentDate = new Date(); + Period period = patientIdentifierType.getPeriodType() + .createPeriod(currentDate); + conjunction.add(Restrictions.between("enrollmentdate", + period.getStartDate(), period.getEndDate())); + } + + disjunction.add(conjunction); + } + + criteria.add(disjunction); + + Number rs = (Number) criteria.setProjection(Projections.rowCount()) + .uniqueResult(); + + if (rs != null && rs.intValue() > 0) { + return PatientService.ERROR_DUPLICATE_IDENTIFIER; + } + } + + if (program != null) { + ValidationCriteria validationCriteria = program.isValid(patient); + + if (validationCriteria != null) { + return PatientService.ERROR_ENROLLMENT; + } + } + + return PatientService.ERROR_NONE; + } + + // ------------------------------------------------------------------------- + // Supportive methods TODO Remplement all this! + // ------------------------------------------------------------------------- + + private String searchPatientSql(boolean count, List searchKeys, + Collection orgunits, Boolean followup, + Collection patientAttributes, + Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max) { + String selector = count ? "count(*) " : "* "; + String sql = "select " + selector + + " from ( select distinct p.patientid,"; + + if (identifierTypes != null) { + for (PatientIdentifierType identifierType : identifierTypes) { + sql += "(select identifier from patientidentifier where patientid=p.patientid and patientidentifiertypeid=" + + identifierType.getId() + + " ) as " + + PREFIX_IDENTIFIER_TYPE + + "_" + + identifierType.getId() + + " ,"; + } + } + + if (patientAttributes != null) { + for (PatientAttribute patientAttribute : patientAttributes) { + sql += "(select value from patientattributevalue where patientid=p.patientid and patientattributeid=" + + patientAttribute.getId() + + " ) as " + + PREFIX_PATIENT_ATTRIBUTE + + "_" + + patientAttribute.getId() + " ,"; + } + } + + String patientWhere = ""; + String patientOperator = " where "; + String patientGroupBy = " GROUP BY p.patientid "; + String otherWhere = ""; + String operator = " where "; + String orderBy = ""; + boolean hasIdentifier = false; + boolean isSearchEvent = false; + boolean isPriorityEvent = false; + Collection orgunitChilrenIds = null; + + if (orgunits != null) { + orgunitChilrenIds = getOrgunitChildren(orgunits); + } + + for (String searchKey : searchKeys) { + String[] keys = searchKey.split("_"); + + if (keys.length <= 1 || keys[1] == null || keys[1].trim().isEmpty() + || keys[1].equals("null")) { + continue; + } + + String id = keys[1]; + String value = ""; + + if (keys.length >= 3) { + value = keys[2]; + } + + if (keys[0].equals(PREFIX_IDENTIFIER_TYPE)) { + + String[] keyValues = id.split(" "); + patientWhere += patientOperator + " ("; + String opt = ""; + for (String v : keyValues) { + patientWhere += opt + + " ( lower(pi.identifier) like '%" + + v + + "%' and pi.patientidentifiertypeid is not null ) "; + opt = "or"; + } + + patientWhere += ")"; + patientOperator = " and "; + hasIdentifier = true; + } else if (keys[0].equals(PREFIX_PATIENT_ATTRIBUTE)) { + sql += "(select value from patientattributevalue where patientid=p.patientid and patientattributeid=" + + id + + " ) as " + + PREFIX_PATIENT_ATTRIBUTE + + "_" + + id + + ","; + + String[] keyValues = value.split(" "); + otherWhere += operator + "("; + String opt = ""; + + for (String v : keyValues) { + otherWhere += opt + " lower(" + PREFIX_PATIENT_ATTRIBUTE + + "_" + id + ") like '%" + v + "%'"; + opt = "or"; + } + + otherWhere += ")"; + operator = " and "; + } else if (keys[0].equals(PREFIX_PROGRAM)) { + sql += "(select programid from programinstance pgi where patientid=p.patientid and programid=" + + id; + + if (statusEnrollment != null) { + sql += " and pgi.status=" + statusEnrollment; + } + + sql += " limit 1 ) as " + PREFIX_PROGRAM + "_" + id + ","; + otherWhere += operator + PREFIX_PROGRAM + "_" + id + "=" + id; + operator = " and "; + } else if (keys[0].equals(PREFIX_PROGRAM_INSTANCE)) { + sql += "(select pi." + + id + + " from programinstance pi where patientid=p.patientid and pi.status=0 "; + + if (keys.length == 5) { + sql += " and pi.programid=" + keys[4]; + } else { + sql += " limit 1 "; + } + + sql += ") as " + PREFIX_PROGRAM_INSTANCE + "_" + id + ","; + otherWhere += operator + PREFIX_PROGRAM_INSTANCE + "_" + id + + keys[2]; + operator = " and "; + } else if (keys[0].equals(PREFIX_PROGRAM_EVENT_BY_STATUS)) { + isSearchEvent = true; + isPriorityEvent = Boolean.parseBoolean(keys[5]); + patientWhere += patientOperator + + "pgi.patientid=p.patientid and "; + patientWhere += "pgi.programid=" + id + " and "; + patientWhere += "pgi.status=" + ProgramInstance.STATUS_ACTIVE; + + String operatorStatus = ""; + String condition = " and ( "; + + for (int index = 6; index < keys.length; index++) { + int statusEvent = Integer.parseInt(keys[index]); + switch (statusEvent) { + case ProgramStageInstance.COMPLETED_STATUS: + patientWhere += condition + + operatorStatus + + "( psi.executiondate is not null and psi.executiondate>='" + + keys[2] + "' and psi.executiondate<='" + + keys[3] + "' and psi.completed=true "; + + // get events by orgunit children + if (keys[4].equals("-1")) { + patientWhere += " and psi.organisationunitid in( " + + TextUtils + .getCommaDelimitedString(orgunitChilrenIds) + + " )"; + } + + // get events by selected orgunit + else if (!keys[4].equals("0")) { + patientWhere += " and psi.organisationunitid=" + + getOrgUnitId(keys); + } + + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + case ProgramStageInstance.VISITED_STATUS: + patientWhere += condition + + operatorStatus + + "( psi.executiondate is not null and psi.executiondate>='" + + keys[2] + "' and psi.executiondate<='" + + keys[3] + "' and psi.completed=false "; + + // get events by orgunit children + if (keys[4].equals("-1")) { + patientWhere += " and psi.organisationunitid in( " + + TextUtils + .getCommaDelimitedString(orgunitChilrenIds) + + " )"; + } + + // get events by selected orgunit + else if (!keys[4].equals("0")) { + patientWhere += " and psi.organisationunitid=" + + getOrgUnitId(keys); + } + + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + case ProgramStageInstance.FUTURE_VISIT_STATUS: + patientWhere += condition + + operatorStatus + + "( psi.executiondate is null and psi.duedate>='" + + keys[2] + + "' and psi.duedate<='" + + keys[3] + + "' and psi.status is not null and (DATE(now()) - DATE(psi.duedate) <= 0) "; + + // get events by orgunit children + if (keys[4].equals("-1")) { + patientWhere += " and p.organisationunitid in( " + + TextUtils + .getCommaDelimitedString(orgunitChilrenIds) + + " )"; + } + + // get events by selected orgunit + else if (!keys[4].equals("0")) { + patientWhere += " and p.organisationunitid=" + + getOrgUnitId(keys); + } + + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + case ProgramStageInstance.LATE_VISIT_STATUS: + patientWhere += condition + + operatorStatus + + "( psi.executiondate is null and psi.duedate>='" + + keys[2] + + "' and psi.duedate<='" + + keys[3] + + "' and psi.status is not null and (DATE(now()) - DATE(psi.duedate) > 0) "; + + // get events by orgunit children + if (keys[4].equals("-1")) { + patientWhere += " and p.organisationunitid in( " + + TextUtils + .getCommaDelimitedString(orgunitChilrenIds) + + " )"; + } + + // get events by selected orgunit + else if (!keys[4].equals("0")) { + patientWhere += " and p.organisationunitid=" + + getOrgUnitId(keys); + } + + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + case ProgramStageInstance.SKIPPED_STATUS: + patientWhere += condition + operatorStatus + + "( psi.status=5 and psi.duedate>='" + + keys[2] + "' and psi.duedate<='" + keys[3] + + "' "; + + // get events by orgunit children + if (keys[4].equals("-1")) { + patientWhere += " and psi.organisationunitid in( " + + TextUtils + .getCommaDelimitedString(orgunitChilrenIds) + + " )"; + } + + // get events by selected orgunit + else if (!keys[4].equals("0")) { + patientWhere += " and p.organisationunitid=" + + getOrgUnitId(keys); + } + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + default: + continue; + } + } + if (condition.isEmpty()) { + patientWhere += ")"; + } + + patientWhere += " and pgi.status=" + + ProgramInstance.STATUS_ACTIVE + " "; + patientOperator = " and "; + } else if (keys[0].equals(PREFIX_PROGRAM_STAGE)) { + isSearchEvent = true; + patientWhere += patientOperator + + "pgi.patientid=p.patientid and psi.programstageid=" + + id + " and "; + patientWhere += "psi.duedate>='" + keys[3] + + "' and psi.duedate<='" + keys[4] + "' and "; + patientWhere += "psi.organisationunitid = " + keys[5] + " and "; + + int statusEvent = Integer.parseInt(keys[2]); + switch (statusEvent) { + case ProgramStageInstance.COMPLETED_STATUS: + patientWhere += "psi.completed=true"; + break; + case ProgramStageInstance.VISITED_STATUS: + patientWhere += "psi.executiondate is not null and psi.completed=false"; + break; + case ProgramStageInstance.FUTURE_VISIT_STATUS: + patientWhere += "psi.executiondate is null and psi.duedate >= now()"; + break; + case ProgramStageInstance.LATE_VISIT_STATUS: + patientWhere += "psi.executiondate is null and psi.duedate < now()"; + break; + default: + break; + } + + patientWhere += " and pgi.status=" + + ProgramInstance.STATUS_ACTIVE + " "; + patientOperator = " and "; + } + } + + if (orgunits != null && !isSearchEvent) { + sql += "(select organisationunitid from patient where patientid=p.patientid and organisationunitid in ( " + + TextUtils + .getCommaDelimitedString(getOrganisationUnitIds(orgunits)) + + " ) ) as orgunitid,"; + otherWhere += operator + + "orgunitid in ( " + + TextUtils + .getCommaDelimitedString(getOrganisationUnitIds(orgunits)) + + " ) "; + } + + sql = sql.substring(0, sql.length() - 1) + " "; // Removing last comma + + String from = " from patient p "; + + if (isSearchEvent) { + String subSQL = " , psi.programstageinstanceid as programstageinstanceid, pgs.name as programstagename, psi.duedate as duedate "; + + if (isPriorityEvent) { + subSQL += ",pgi.followup "; + orderBy = " ORDER BY pgi.followup desc, p.patientid, duedate asc "; + patientGroupBy += ",pgi.followup "; + } else { + orderBy = " ORDER BY p.patientid, duedate asc "; + } + + sql = sql + + subSQL + + from + + " inner join programinstance pgi on " + + " (pgi.patientid=p.patientid) " + + " inner join programstageinstance psi on (psi.programinstanceid=pgi.programinstanceid) " + + " inner join programstage pgs on (pgs.programstageid=psi.programstageid) "; + + patientGroupBy += ",psi.programstageinstanceid, pgs.name, psi.duedate "; + + from = " "; + } + + if (hasIdentifier) { + sql += from + + " left join patientidentifier pi on p.patientid=pi.patientid "; + from = " "; + } + + sql += from + patientWhere; + if (followup != null) { + sql += " AND pgi.followup=" + followup; + } + if (isSearchEvent) { + sql += patientGroupBy; + } + sql += orderBy; + sql += " ) as searchresult"; + sql += otherWhere; + + if (min != null && max != null) { + sql += " limit " + max + " offset " + min; + } + + log.info("Search patient SQL: " + sql); + + return sql; + } + + private Integer getOrgUnitId(String[] keys) { + Integer orgUnitId; + try { + orgUnitId = Integer.parseInt(keys[4]); + } catch (NumberFormatException e) { + // handle as uid + OrganisationUnit ou = organisationUnitService + .getOrganisationUnit(keys[4]); + orgUnitId = ou.getId(); + } + return orgUnitId; + } + + private Collection getOrgunitChildren( + Collection orgunits) { + Collection orgUnitIds = new HashSet(); + + if (orgunits != null) { + for (OrganisationUnit orgunit : orgunits) { + orgUnitIds.addAll(organisationUnitService + .getOrganisationUnitHierarchy().getChildren( + orgunit.getId())); + orgUnitIds.remove(orgunit.getId()); + } + } + + if (orgUnitIds.size() == 0) { + orgUnitIds.add(0); + } + + return orgUnitIds; + } + + private Collection getOrganisationUnitIds( + Collection orgunits) { + Collection orgUnitIds = new HashSet(); + + for (OrganisationUnit orgUnit : orgunits) { + orgUnitIds.add(orgUnit.getId()); + } + + if (orgUnitIds.size() == 0) { + orgUnitIds.add(0); + } + + return orgUnitIds; + } + + @SuppressWarnings({ "unchecked" }) + @Override + public Collection getByPatientAttributeValue(String searchText, + int patientAttributeId, Integer min, Integer max) { + + String hql = "FROM PatientAttributeValue pav WHERE lower (pav.value) LIKE lower ('%" + + searchText + + "%') AND pav.patientAttribute.id =:patientAttributeId"; + + Query query = getQuery(hql); + + query.setInteger("patientAttributeId", patientAttributeId); + + if (min != null && max != null) { + query.setFirstResult(min).setMaxResults(max); + } + + List patients = new ArrayList(); + Collection patientAttributeValue = query.list(); + for (PatientAttributeValue pv : patientAttributeValue) { + patients.add(pv.getPatient()); + } + + return patients; + + } + } \ No newline at end of file === modified file 'dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/namebaseddataentry/action/FindBeneficiarytAction.java' --- dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/namebaseddataentry/action/FindBeneficiarytAction.java 2013-12-16 15:45:17 +0000 +++ dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/namebaseddataentry/action/FindBeneficiarytAction.java 2014-01-22 04:25:46 +0000 @@ -28,119 +28,144 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.opensymphony.xwork2.Action; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + import org.hisp.dhis.patient.Patient; import org.hisp.dhis.patient.PatientService; - -import java.util.Collection; - -public class FindBeneficiarytAction - implements Action -{ - private static final String REDIRECT = "redirect"; - - // ------------------------------------------------------------------------- - // Dependencies - // ------------------------------------------------------------------------- - - private PatientService patientService; - - public void setPatientService( PatientService patientService ) - { - this.patientService = patientService; - } - - // ------------------------------------------------------------------------- - // Input & Output - // ------------------------------------------------------------------------- - - private Collection patients; - - public Collection getPatients() - { - return patients; - } - - public void setPatients( Collection patients ) - { - this.patients = patients; - } - - private String keyword; - - public String getKeyword() - { - return keyword; - } - - public void setKeyword( String keyword ) - { - this.keyword = keyword; - } - - private Integer organisationUnitId; - - public Integer getOrganisationUnitId() - { - return organisationUnitId; - } - - public void setOrganisationUnitId( Integer organisationUnitId ) - { - this.organisationUnitId = organisationUnitId; - } - - private Integer patientId; - - public Integer getPatientId() - { - return patientId; - } - - public void setPatientId( Integer patientId ) - { - this.patientId = patientId; - } - - // Use in search related patient - - private Integer originalPatientId; - - public void setOriginalPatientId( Integer originalPatientId ) - { - this.originalPatientId = originalPatientId; - } - - public Integer getOriginalPatientId() - { - return originalPatientId; - } - - private Integer relationshipTypeId; - - public Integer getRelationshipTypeId() - { - return relationshipTypeId; - } - - public void setRelationshipTypeId( Integer relationshipTypeId ) - { - this.relationshipTypeId = relationshipTypeId; - } - - @Override - public String execute() - throws Exception - { - patients = patientService.getPatientsForMobile( keyword, organisationUnitId ); - - if ( patients.size() == 1 ) - { - Patient patient = patients.iterator().next(); - patientId = patient.getId(); - return REDIRECT; - } - return SUCCESS; - } +import org.hisp.dhis.patientattributevalue.PatientAttributeValue; + +import com.opensymphony.xwork2.Action; + +public class FindBeneficiarytAction implements Action { + private static final String REDIRECT = "redirect"; + + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + private PatientService patientService; + + public void setPatientService(PatientService patientService) { + this.patientService = patientService; + } + + // ------------------------------------------------------------------------- + // Input & Output + // ------------------------------------------------------------------------- + + private Collection patients; + + public Collection getPatients() { + return patients; + } + + public void setPatients(Collection patients) { + this.patients = patients; + } + + private Set pavSet; + + public Set getPavSet() { + return pavSet; + } + + public void setPavSet(Set pavSet) { + this.pavSet = pavSet; + } + + private Set patientAttributes; + + public Set getPatientAttributes() { + return patientAttributes; + } + + public void setPatientAttributes( + Set patientAttributes) { + this.patientAttributes = patientAttributes; + } + + private String keyword; + + public String getKeyword() { + return keyword; + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } + + private Integer organisationUnitId; + + public Integer getOrganisationUnitId() { + return organisationUnitId; + } + + public void setOrganisationUnitId(Integer organisationUnitId) { + this.organisationUnitId = organisationUnitId; + } + + private Integer patientAttributeId; + + public Integer getPatientAttributeId() { + return patientAttributeId; + } + + public void setPatientAttributeId(Integer patientAttributeId) { + this.patientAttributeId = patientAttributeId; + } + + private Integer patientId; + + public Integer getPatientId() { + return patientId; + } + + public void setPatientId(Integer patientId) { + this.patientId = patientId; + } + + // Use in search related patient + + private Integer originalPatientId; + + public void setOriginalPatientId(Integer originalPatientId) { + this.originalPatientId = originalPatientId; + } + + public Integer getOriginalPatientId() { + return originalPatientId; + } + + private Integer relationshipTypeId; + + public Integer getRelationshipTypeId() { + return relationshipTypeId; + } + + public void setRelationshipTypeId(Integer relationshipTypeId) { + this.relationshipTypeId = relationshipTypeId; + } + + @Override + public String execute() throws Exception { + + patients = patientService.searchPatientsForMobile(keyword, + organisationUnitId, patientAttributeId); + pavSet = new HashSet(); + + for (Patient p : patients) { + pavSet.addAll(p.getAttributeValues()); + } + + if (patients.size() == 1) { + Patient patient = patients.iterator().next(); + patientId = patient.getId(); + + return REDIRECT; + } + return SUCCESS; + } } === modified file 'dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/namebaseddataentry/action/GetFindBeneficiaryFormAction.java' --- dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/namebaseddataentry/action/GetFindBeneficiaryFormAction.java 2013-12-16 15:45:17 +0000 +++ dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/namebaseddataentry/action/GetFindBeneficiaryFormAction.java 2014-01-22 04:25:46 +0000 @@ -34,119 +34,135 @@ import java.util.List; import java.util.Set; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.patient.PatientAttribute; +import org.hisp.dhis.patient.PatientAttributeService; import org.hisp.dhis.user.CurrentUserService; import org.hisp.dhis.user.User; import com.opensymphony.xwork2.Action; -public class GetFindBeneficiaryFormAction - implements Action -{ - // ------------------------------------------------------------------------- - // Dependencies - // ------------------------------------------------------------------------- - - private CurrentUserService currentUserService; - - public void setCurrentUserService( CurrentUserService currentUserService ) - { - this.currentUserService = currentUserService; - } - - // ------------------------------------------------------------------------- - // Input & Output - // ------------------------------------------------------------------------- - - private Integer orgUnitId; - - public Integer getOrgUnitId() - { - return orgUnitId; - } - - public void setOrgUnitId( Integer orgUnitId ) - { - this.orgUnitId = orgUnitId; - } - - private Set organisationUnits; - - public Set getOrganisationUnits() - { - return organisationUnits; - } - - public void setOrganisationUnits( Set organisationUnits ) - { - this.organisationUnits = organisationUnits; - } - - private User user; - - public User getUser() - { - return user; - } - - public void setUser( User user ) - { - this.user = user; - } - - // use in find relation person - - private Integer originalPatientId; - - public Integer getOriginalPatientId() - { - return originalPatientId; - } - - public void setOriginalPatientId( Integer originalPatientId ) - { - this.originalPatientId = originalPatientId; - } - - private Integer relationshipTypeId; - - public Integer getRelationshipTypeId() - { - return relationshipTypeId; - } - - public void setRelationshipTypeId( Integer relationshipTypeId ) - { - this.relationshipTypeId = relationshipTypeId; - } - - @Override - public String execute() - throws Exception - { - user = currentUserService.getCurrentUser(); - Collection basicOrganisationUnits = currentUserService.getCurrentUser() - .getOrganisationUnits(); - organisationUnits = new HashSet(); - - for ( OrganisationUnit organisationUnit : basicOrganisationUnits ) - { - organisationUnits.addAll( this.getAllParentOrganisationUnits( organisationUnit ) ); - } - - return SUCCESS; - } - - private Collection getAllParentOrganisationUnits( OrganisationUnit organisationUnit ) - { - List parents = new ArrayList(); - parents.add( organisationUnit ); - - while ( organisationUnit.getParent() != null ) - { - parents.add( organisationUnit.getParent() ); - organisationUnit = organisationUnit.getParent(); - } - return parents; - } +public class GetFindBeneficiaryFormAction implements Action { + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + private CurrentUserService currentUserService; + + public void setCurrentUserService(CurrentUserService currentUserService) { + this.currentUserService = currentUserService; + } + + private PatientAttributeService patientAttributeService; + + public void setPatientAttributeService( + PatientAttributeService patientAttributeService) { + this.patientAttributeService = patientAttributeService; + } + + // ------------------------------------------------------------------------- + // Input & Output + // ------------------------------------------------------------------------- + + private Integer patientAttributeId; + + public Integer getPatientAttributeId() { + return patientAttributeId; + } + + public void setPatientAttributeId(Integer patientAttributeId) { + this.patientAttributeId = patientAttributeId; + } + + private Integer orgUnitId; + + public Integer getOrgUnitId() { + return orgUnitId; + } + + public void setOrgUnitId(Integer orgUnitId) { + this.orgUnitId = orgUnitId; + } + + private Collection patientAttributes; + + public Collection getPatientAttributes() { + return patientAttributes; + } + + public void setPatientAttributes( + Collection patientAttributes) { + this.patientAttributes = patientAttributes; + } + + private Set organisationUnits; + + public Set getOrganisationUnits() { + return organisationUnits; + } + + public void setOrganisationUnits(Set organisationUnits) { + this.organisationUnits = organisationUnits; + } + + private User user; + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + // use in find relation person + + private Integer originalPatientId; + + public Integer getOriginalPatientId() { + return originalPatientId; + } + + public void setOriginalPatientId(Integer originalPatientId) { + this.originalPatientId = originalPatientId; + } + + private Integer relationshipTypeId; + + public Integer getRelationshipTypeId() { + return relationshipTypeId; + } + + public void setRelationshipTypeId(Integer relationshipTypeId) { + this.relationshipTypeId = relationshipTypeId; + } + + @Override + public String execute() throws Exception { + user = currentUserService.getCurrentUser(); + Collection basicOrganisationUnits = currentUserService + .getCurrentUser().getOrganisationUnits(); + organisationUnits = new HashSet(); + + for (OrganisationUnit organisationUnit : basicOrganisationUnits) { + organisationUnits.addAll(this + .getAllParentOrganisationUnits(organisationUnit)); + } + + patientAttributes = patientAttributeService.getAllPatientAttributes(); + + return SUCCESS; + } + + private Collection getAllParentOrganisationUnits( + OrganisationUnit organisationUnit) { + List parents = new ArrayList(); + parents.add(organisationUnit); + + while (organisationUnit.getParent() != null) { + parents.add(organisationUnit.getParent()); + organisationUnit = organisationUnit.getParent(); + } + return parents; + } } === modified file 'dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml' --- dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml 2013-12-30 21:55:24 +0000 +++ dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml 2014-01-22 04:25:46 +0000 @@ -1,30 +1,35 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -38,30 +43,25 @@ - + - + - + class="org.hisp.dhis.light.dataentry.action.GetDataSetsAction" scope="prototype"> + - + class="org.hisp.dhis.light.dataentry.action.GetPeriodsAction" scope="prototype"> + @@ -76,15 +76,13 @@ ref="org.hisp.dhis.organisationunit.OrganisationUnitService" /> - + + class="org.hisp.dhis.light.dataentry.action.MarkComplete" scope="prototype"> @@ -93,10 +91,9 @@ ref="org.hisp.dhis.dataset.CompleteDataSetRegistrationService" /> - + + class="org.hisp.dhis.light.dataentry.action.UndoCompleteAction" scope="prototype"> @@ -112,8 +109,7 @@ ref="org.hisp.dhis.organisationunit.OrganisationUnitService" /> - + - + @@ -146,7 +141,7 @@ + scope="prototype"> + scope="prototype"> + scope="prototype"> + ref="org.hisp.dhis.program.ProgramStageInstanceService" /> - + + scope="prototype"> + ref="org.hisp.dhis.program.ProgramStageInstanceService" /> + scope="prototype"> @@ -198,52 +193,62 @@ ref="org.hisp.dhis.patientdatavalue.PatientDataValueService" /> - + ref="org.hisp.dhis.program.ProgramStageSectionService" /> + + scope="prototype"> - - - - - - - - + + + + + + + + + scope="prototype"> + scope="prototype"> + + + scope="prototype"> + + - + - + + scope="prototype"> @@ -272,7 +279,7 @@ + scope="prototype"> @@ -280,7 +287,7 @@ + scope="prototype"> + scope="prototype"> @@ -310,7 +317,7 @@ + scope="prototype"> @@ -319,7 +326,7 @@ + scope="prototype"> @@ -411,8 +418,7 @@ - + - + - + + scope="prototype"> - + + class="org.hisp.dhis.light.settings.action.GetSettingsAction" scope="prototype"> @@ -532,60 +537,57 @@ + class="org.hisp.dhis.light.message.action.GetMessagesAction" scope="prototype"> + class="org.hisp.dhis.light.message.action.GetMessageAction" scope="prototype"> + class="org.hisp.dhis.light.message.action.SendReplyAction" scope="prototype"> + class="org.hisp.dhis.light.message.action.SendFeedbackAction" scope="prototype"> - + - - - + - + - + - + + ref="org.hisp.dhis.organisationunit.OrganisationUnitService" /> @@ -596,22 +598,20 @@ ref="org.hisp.dhis.patientdatavalue.PatientDataValueService" /> - + + scope="prototype"> - - + + === modified file 'dhis-2/dhis-web/dhis-web-light/src/main/resources/org/hisp/dhis/light/i18n_module.properties' --- dhis-2/dhis-web/dhis-web-light/src/main/resources/org/hisp/dhis/light/i18n_module.properties 2013-11-09 16:08:46 +0000 +++ dhis-2/dhis-web/dhis-web-light/src/main/resources/org/hisp/dhis/light/i18n_module.properties 2014-01-22 04:25:46 +0000 @@ -132,4 +132,5 @@ search_user=Search user by name last_recipients=Last recipients search_orgunit=Search Organisation Unit -date_of_birth_hint=*Approximated: enter age. Declared or Verified: enter date in format [yyyy-mm-dd] \ No newline at end of file +date_of_birth_hint=*Approximated: enter age. Declared or Verified: enter date in format [yyyy-mm-dd] +select_attribute=Select attribute \ No newline at end of file === modified file 'dhis-2/dhis-web/dhis-web-light/src/main/resources/struts.xml' --- dhis-2/dhis-web/dhis-web-light/src/main/resources/struts.xml 2013-11-08 11:59:56 +0000 +++ dhis-2/dhis-web/dhis-web-light/src/main/resources/struts.xml 2014-01-22 04:25:46 +0000 @@ -188,6 +188,7 @@ /dhis-web-light/namebased/findBeneficiaryForm.vm F_PATIENT_SEARCH + === modified file 'dhis-2/dhis-web/dhis-web-light/src/main/webapp/dhis-web-light/namebased/beneficiaryList.vm' --- dhis-2/dhis-web/dhis-web-light/src/main/webapp/dhis-web-light/namebased/beneficiaryList.vm 2013-09-16 17:07:25 +0000 +++ dhis-2/dhis-web/dhis-web-light/src/main/webapp/dhis-web-light/namebased/beneficiaryList.vm 2014-01-22 04:25:46 +0000 @@ -2,8 +2,10 @@

=== modified file 'dhis-2/dhis-web/dhis-web-light/src/main/webapp/dhis-web-light/namebased/findBeneficiaryForm.vm' --- dhis-2/dhis-web/dhis-web-light/src/main/webapp/dhis-web-light/namebased/findBeneficiaryForm.vm 2012-10-24 09:02:06 +0000 +++ dhis-2/dhis-web/dhis-web-light/src/main/webapp/dhis-web-light/namebased/findBeneficiaryForm.vm 2014-01-22 04:25:46 +0000 @@ -11,7 +11,13 @@

- + + #if( $validationMap.get( "keyword" ) )
$i18n.getString($validationMap.get( "fullName" )) #end