← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 13839: (light) fixed search patient for mobile after merging patient identifer object

 

------------------------------------------------------------
revno: 13839
committer: Hong Em <em.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2014-01-24 14:23:04 +0700
message:
  (light) fixed search patient for mobile after merging patient identifer object
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java
  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/hibernate/HibernatePatientStore.java
  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/resources/META-INF/dhis/beans.xml


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== 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-23 14:18:27 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java	2014-01-24 07:23:04 +0000
@@ -44,345 +44,440 @@
  * @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<Patient> getAllPatients();
-
-    /**
-     * Retrieve patients for mobile base on identifier value
-     * 
-     * @param searchText value
-     * @param orgUnitId
-     * 
-     * @return Patient List
-     */
-    Collection<Patient> 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<Patient> getPatients( OrganisationUnit organisationUnit, Integer min, Integer max );
-
-    /**
-     * Retrieve patients who enrolled into a program with active status
-     * 
-     * @param program Program
-     * @return Patient list
-     */
-    Collection<Patient> getPatients( Program program );
-
-    /**
-     * Retrieve patients registered in a orgunit and enrolled into a program
-     * with active status
-     * 
-     * @param organisationUnit
-     * @param program
-     * @return
-     */
-    Collection<Patient> getPatients( OrganisationUnit organisationUnit, Program program );
-
-    /**
-     * Retrieve patients base on Attribute 
-     * 
-     * @param attributeId
-     * @param value
-     * @return
-     */
-    Collection<Patient> getPatient( 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<Patient> getPatients( OrganisationUnit organisationUnit, Program program, Integer min, Integer max );
-
-    /**
-     * Sort the result by PatientAttribute
-     * 
-     * @param patients
-     * @param patientAttribute
-     * @return Patient List
-     */
-    Collection<Patient> sortPatientsByAttribute( Collection<Patient> patients, PatientAttribute patientAttribute );
-
-    /**
-     * Get patients who has the same representative
-     * 
-     * @params patient The representatives
-     * 
-     * @return Patient List
-     * **/
-    Collection<Patient> 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<PatientAttributeValue> 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<PatientAttributeValue> valuesForSave, List<PatientAttributeValue> valuesForUpdate,
-        Collection<PatientAttributeValue> 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 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 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<Patient> searchPatients( List<String> searchKeys, Collection<OrganisationUnit> orgunit,
-        Boolean followup, Collection<PatientAttribute> patientAttributes, 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
-     *        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<String> searchKeys, Collection<OrganisationUnit> 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
-     *        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<String> getPatientPhoneNumbers( List<String> searchKeys, Collection<OrganisationUnit> 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
-     *        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<Integer> getProgramStageInstances( List<String> searchKeys, Collection<OrganisationUnit> 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
-     *        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<String> searchKeys, Collection<OrganisationUnit> 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<Patient> 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 attributes of this
-     *        program and put attribute values of patients into the result
-     * @param searchKeys The key for searching patients by attribute values
-     *        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<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Integer statusEnrollment, I18n i18n );
-
-    /**
-     * Validate patient attributes 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 unique attribute values of the patient
-     * 
-     * @return Error code 0 : Validation is OK 1 : The attribute 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<Patient> getAllPatients();
+
+	/**
+	 * Retrieve patients for mobile base on identifier value
+	 * 
+	 * @param searchText
+	 *            value
+	 * @param orgUnitId
+	 * 
+	 * @return Patient List
+	 */
+	Collection<Patient> 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<Patient> getPatients(OrganisationUnit organisationUnit,
+			Integer min, Integer max);
+
+	/**
+	 * Retrieve patients who enrolled into a program with active status
+	 * 
+	 * @param program
+	 *            Program
+	 * @return Patient list
+	 */
+	Collection<Patient> getPatients(Program program);
+
+	/**
+	 * Retrieve patients registered in a orgunit and enrolled into a program
+	 * with active status
+	 * 
+	 * @param organisationUnit
+	 * @param program
+	 * @return
+	 */
+	Collection<Patient> getPatients(OrganisationUnit organisationUnit,
+			Program program);
+
+	/**
+	 * Retrieve patients base on Attribute
+	 * 
+	 * @param attributeId
+	 * @param value
+	 * @return
+	 */
+	Collection<Patient> getPatient(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<Patient> getPatients(OrganisationUnit organisationUnit,
+			Program program, Integer min, Integer max);
+
+	/**
+	 * Sort the result by PatientAttribute
+	 * 
+	 * @param patients
+	 * @param patientAttribute
+	 * @return Patient List
+	 */
+	Collection<Patient> sortPatientsByAttribute(Collection<Patient> patients,
+			PatientAttribute patientAttribute);
+
+	/**
+	 * Get patients who has the same representative
+	 * 
+	 * @params patient The representatives
+	 * 
+	 * @return Patient List
+	 * **/
+	Collection<Patient> 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<PatientAttributeValue> 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<PatientAttributeValue> valuesForSave,
+			List<PatientAttributeValue> valuesForUpdate,
+			Collection<PatientAttributeValue> 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 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 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<Patient> searchPatients(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunit, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			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 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<String> searchKeys,
+			Collection<OrganisationUnit> 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 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<String> getPatientPhoneNumbers(List<String> searchKeys,
+			Collection<OrganisationUnit> 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 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<Integer> getProgramStageInstances(List<String> searchKeys,
+			Collection<OrganisationUnit> 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 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<String> searchKeys,
+			Collection<OrganisationUnit> 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<Patient> 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 attributes of this program
+	 *            and put attribute values of patients into the result
+	 * @param searchKeys
+	 *            The key for searching patients by attribute values 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<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Integer statusEnrollment, I18n i18n);
+
+	/**
+	 * Validate patient attributes 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 unique attribute values of the patient
+	 * 
+	 * @return Error code 0 : Validation is OK 1 : The attribute is duplicated 2
+	 *         : Violate validation criteria of the program
+	 */
+	int validatePatient(Patient patient, Program program);
+
+	/**
+	 * Retrieve patients for mobile base on identifier value
+	 * 
+	 * @param searchText
+	 *            value
+	 * @param orgUnitId
+	 * @param patientAttributeId
+	 * @return Patient List
+	 */
+
+	Collection<Patient> searchPatientsForMobile(String searchText,
+			int orgUnitId, int patientAttributeId);
+
+	/**
+	 * Search patients by patient attribute value (performs partial search)
+	 * 
+	 * @param patient
+	 *            attribute value The string for searching by patient attribute
+	 *            value
+	 * @param min
+	 * @param max
+	 * 
+	 * @return List of patient
+	 */
+	Collection<Patient> getPatientsByAttributeValue(String searchText, int patientAttributeId,
+			Integer min, Integer max);
 }

=== 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-23 14:18:27 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java	2014-01-24 07:23:04 +0000
@@ -40,199 +40,240 @@
  * @author Abyot Asalefew Gizaw
  * @version $Id$
  */
-public interface PatientStore
-    extends GenericIdentifiableObjectStore<Patient>
-{
-    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<Patient> 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 attributes of this
-     *        program and put attribute values of patients into the result
-     * @param min
-     * @param max
-     * 
-     * @return List of patients
-     */
-    Collection<Patient> getByOrgUnitProgram( OrganisationUnit organisationUnit, Program program, Integer min,
-        Integer max );
-
-    List<Patient> query( TrackedEntityQueryParams params );
-
-    /**
-     * Search patient who has the same representative
-     * 
-     * @param patient Representative
-     * 
-     * @return List of patients
-     */
-    Collection<Patient> 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 attributes of this
-     *        program and put attribute values 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
-     *        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<String> searchKeys, Collection<OrganisationUnit> 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<Patient> 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
-     *        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 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<Patient> search( List<String> searchKeys, Collection<OrganisationUnit> orgunit, Boolean followup,
-        Collection<PatientAttribute> patientAttributes, Integer statusEnrollment, Integer min, Integer max );
-
-    /**
-     * Search events which meet the criteria for searching
-     * 
-     * @param searchKeys The key for searching patients by attribute values
-     *        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 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<Integer> getProgramStageInstances( List<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Collection<PatientAttribute> patientAttributes, 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<Patient> 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
-     *        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 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<String> searchKeys, Collection<OrganisationUnit> orgunit,
-        Boolean followup, Collection<PatientAttribute> patientAttributes, Integer statusEnrollment, Integer min,
-        Integer max );
-
-    /**
-     * Validate patient attribute values 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 attribute values of the patient
-     * 
-     * @return Error code 0 : Validation is OK 1 : The attribute value is duplicated
-     *         2 : Violate validation criteria of the program
-     */
-    int validate( Patient patient, Program program );
+public interface PatientStore extends GenericIdentifiableObjectStore<Patient> {
+	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<Patient> 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 attributes of this program
+	 *            and put attribute values of patients into the result
+	 * @param min
+	 * @param max
+	 * 
+	 * @return List of patients
+	 */
+	Collection<Patient> getByOrgUnitProgram(OrganisationUnit organisationUnit,
+			Program program, Integer min, Integer max);
+
+	List<Patient> query(TrackedEntityQueryParams params);
+
+	/**
+	 * Search patient who has the same representative
+	 * 
+	 * @param patient
+	 *            Representative
+	 * 
+	 * @return List of patients
+	 */
+	Collection<Patient> 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 attributes of this program
+	 *            and put attribute values 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 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<String> searchKeys,
+			Collection<OrganisationUnit> 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<Patient> 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 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 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<Patient> search(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunit, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			Integer statusEnrollment, Integer min, Integer max);
+
+	/**
+	 * Search events which meet the criteria for searching
+	 * 
+	 * @param searchKeys
+	 *            The key for searching patients by attribute values 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 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<Integer> getProgramStageInstances(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			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<Patient> 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 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 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<String> searchKeys,
+			Collection<OrganisationUnit> orgunit, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			Integer statusEnrollment, Integer min, Integer max);
+
+	/**
+	 * Validate patient attribute values 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 attribute values of the patient
+	 * 
+	 * @return Error code 0 : Validation is OK 1 : The attribute value is
+	 *         duplicated 2 : Violate validation criteria of the program
+	 */
+	int validate(Patient patient, Program program);
+
+	Collection<Patient> getByPatientAttributeValue(String searchText,
+			int patientAttributeId, Integer min, Integer max);
 }

=== 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-23 14:18:27 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientService.java	2014-01-24 07:23:04 +0000
@@ -57,489 +57,491 @@
  * @version $Id$
  */
 @Transactional
-public class DefaultPatientService
-    implements PatientService
-{
-    // -------------------------------------------------------------------------
-    // Dependencies
-    // -------------------------------------------------------------------------
-
-    private PatientStore patientStore;
-
-    public void setPatientStore( PatientStore patientStore )
-    {
-        this.patientStore = patientStore;
-    }
-
-    private PatientAttributeValueService patientAttributeValueService;
-
-    public void setPatientAttributeValueService( PatientAttributeValueService patientAttributeValueService )
-    {
-        this.patientAttributeValueService = patientAttributeValueService;
-    }
-
-    private PatientAttributeService patientAttributeService;
-
-    public void setPatientAttributeService( PatientAttributeService patientAttributeService )
-    {
-        this.patientAttributeService = patientAttributeService;
-    }
-
-    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<PatientAttributeValue> 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<Patient> getAllPatients()
-    {
-        return patientStore.getAll();
-    }
-
-    @Override
-    public Collection<Patient> getPatientsForMobile( String searchText, int orgUnitId )
-    {
-        Set<Patient> patients = new HashSet<Patient>();
-        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<Patient> toRemoveList = new HashSet<Patient>();
-
-            for ( Patient patient : patients )
-            {
-                if ( patient.getOrganisationUnit().getId() != orgUnitId )
-                {
-                    toRemoveList.add( patient );
-                }
-            }
-
-            patients.removeAll( toRemoveList );
-        }
-
-        return patients;
-    }
-
-    @Override
-    public Collection<Patient> getPatients( OrganisationUnit organisationUnit, Integer min, Integer max )
-    {
-        return patientStore.getByOrgUnit( organisationUnit, min, max );
-    }
-
-    @Override
-    public Collection<Patient> getPatients( Program program )
-    {
-        return patientStore.getByProgram( program, 0, Integer.MAX_VALUE );
-    }
-
-    @Override
-    public Collection<Patient> getPatients( OrganisationUnit organisationUnit, Program program )
-    {
-        return patientStore.getByOrgUnitProgram( organisationUnit, program, 0, Integer.MAX_VALUE );
-    }
-
-    @Override
-    public Collection<Patient> getPatient( Integer attributeId, String value )
-    {
-        PatientAttribute attribute = patientAttributeService.getPatientAttribute( attributeId );
-        if ( attribute != null )
-        {
-            return patientAttributeValueService.getPatient( attribute, value );
-        }
-
-        return null;
-    }
-
-    @Override
-    public Collection<Patient> sortPatientsByAttribute( Collection<Patient> patients, PatientAttribute patientAttribute )
-    {
-        Collection<Patient> sortedPatients = new ArrayList<Patient>();
-
-        // ---------------------------------------------------------------------
-        // Better to fetch all attribute values at once than fetching the
-        // required attribute value of each patient using loop
-        // ---------------------------------------------------------------------
-
-        Collection<PatientAttributeValue> 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<PatientAttributeValue> valuesForSave, List<PatientAttributeValue> valuesForUpdate,
-        Collection<PatientAttributeValue> 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<Patient> 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<Patient> getRepresentatives( Patient patient )
-    {
-        return patientStore.getRepresentatives( patient );
-    }
-
-    @Override
-    public Collection<Patient> searchPatients( List<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Collection<PatientAttribute> patientAttributes,
-         Integer statusEnrollment, Integer min, Integer max )
-    {
-        return patientStore.search( searchKeys, orgunits, followup, patientAttributes, 
-            statusEnrollment, min, max );
-    }
-
-    @Override
-    public int countSearchPatients( List<String> searchKeys, Collection<OrganisationUnit> orgunits, Boolean followup,
-        Integer statusEnrollment )
-    {
-        return patientStore.countSearch( searchKeys, orgunits, followup, statusEnrollment );
-    }
-
-    @Override
-    public Collection<String> getPatientPhoneNumbers( List<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Integer statusEnrollment, Integer min, Integer max )
-    {
-        Collection<Patient> patients = patientStore.search( searchKeys, orgunits, followup, null,
-            statusEnrollment, min, max );
-        Set<String> phoneNumbers = new HashSet<String>();
-
-        for ( Patient patient : patients )
-        {
-            Collection<PatientAttributeValue> 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<Integer> getProgramStageInstances( List<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Integer statusEnrollment, Integer min, Integer max )
-    {
-        return patientStore.getProgramStageInstances( searchKeys, orgunits, followup, null, statusEnrollment,
-            min, max );
-    }
-
-    @Override
-    public Collection<Patient> getPatientsByPhone( String phoneNumber, Integer min, Integer max )
-    {
-        return patientStore.getByPhoneNumber( phoneNumber, min, max );
-    }
-
-    @Override
-    public Grid getScheduledEventsReport( List<String> searchKeys, Collection<OrganisationUnit> 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<PatientAttribute> 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, 
-            statusEnrollment, min, max );
-    }
-
-    @Override
-    public Grid getTrackingEventsReport( Program program, List<String> searchKeys,
-        Collection<OrganisationUnit> 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<PatientAttribute> patientAttributes = program.getAttributes();
-
-        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 ) );
-        grid.addHeader( new GridHeader( i18n.getString( "risk" ), false, true ) );
-
-        return patientStore.getPatientEventReport( grid, searchKeys, orgunits, followup, patientAttributes, 
-            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 PatientAttributeValueService patientAttributeValueService;
+
+	public void setPatientAttributeValueService(
+			PatientAttributeValueService patientAttributeValueService) {
+		this.patientAttributeValueService = patientAttributeValueService;
+	}
+
+	private PatientAttributeService patientAttributeService;
+
+	public void setPatientAttributeService(
+			PatientAttributeService patientAttributeService) {
+		this.patientAttributeService = patientAttributeService;
+	}
+
+	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<PatientAttributeValue> 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<Patient> getAllPatients() {
+		return patientStore.getAll();
+	}
+
+	@Override
+	public Collection<Patient> getPatientsForMobile(String searchText,
+			int orgUnitId) {
+		Set<Patient> patients = new HashSet<Patient>();
+		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<Patient> toRemoveList = new HashSet<Patient>();
+
+			for (Patient patient : patients) {
+				if (patient.getOrganisationUnit().getId() != orgUnitId) {
+					toRemoveList.add(patient);
+				}
+			}
+
+			patients.removeAll(toRemoveList);
+		}
+
+		return patients;
+	}
+
+	@Override
+	public Collection<Patient> getPatients(OrganisationUnit organisationUnit,
+			Integer min, Integer max) {
+		return patientStore.getByOrgUnit(organisationUnit, min, max);
+	}
+
+	@Override
+	public Collection<Patient> getPatients(Program program) {
+		return patientStore.getByProgram(program, 0, Integer.MAX_VALUE);
+	}
+
+	@Override
+	public Collection<Patient> getPatients(OrganisationUnit organisationUnit,
+			Program program) {
+		return patientStore.getByOrgUnitProgram(organisationUnit, program, 0,
+				Integer.MAX_VALUE);
+	}
+
+	@Override
+	public Collection<Patient> getPatient(Integer attributeId, String value) {
+		PatientAttribute attribute = patientAttributeService
+				.getPatientAttribute(attributeId);
+		if (attribute != null) {
+			return patientAttributeValueService.getPatient(attribute, value);
+		}
+
+		return null;
+	}
+
+	@Override
+	public Collection<Patient> sortPatientsByAttribute(
+			Collection<Patient> patients, PatientAttribute patientAttribute) {
+		Collection<Patient> sortedPatients = new ArrayList<Patient>();
+
+		// ---------------------------------------------------------------------
+		// Better to fetch all attribute values at once than fetching the
+		// required attribute value of each patient using loop
+		// ---------------------------------------------------------------------
+
+		Collection<PatientAttributeValue> 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<PatientAttributeValue> valuesForSave,
+			List<PatientAttributeValue> valuesForUpdate,
+			Collection<PatientAttributeValue> 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<Patient> 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<Patient> getRepresentatives(Patient patient) {
+		return patientStore.getRepresentatives(patient);
+	}
+
+	@Override
+	public Collection<Patient> searchPatients(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			Integer statusEnrollment, Integer min, Integer max) {
+		return patientStore.search(searchKeys, orgunits, followup,
+				patientAttributes, statusEnrollment, min, max);
+	}
+
+	@Override
+	public int countSearchPatients(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Integer statusEnrollment) {
+		return patientStore.countSearch(searchKeys, orgunits, followup,
+				statusEnrollment);
+	}
+
+	@Override
+	public Collection<String> getPatientPhoneNumbers(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Integer statusEnrollment, Integer min, Integer max) {
+		Collection<Patient> patients = patientStore.search(searchKeys,
+				orgunits, followup, null, statusEnrollment, min, max);
+		Set<String> phoneNumbers = new HashSet<String>();
+
+		for (Patient patient : patients) {
+			Collection<PatientAttributeValue> 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<Integer> getProgramStageInstances(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Integer statusEnrollment, Integer min, Integer max) {
+		return patientStore.getProgramStageInstances(searchKeys, orgunits,
+				followup, null, statusEnrollment, min, max);
+	}
+
+	@Override
+	public Collection<Patient> getPatientsByPhone(String phoneNumber,
+			Integer min, Integer max) {
+		return patientStore.getByPhoneNumber(phoneNumber, min, max);
+	}
+
+	@Override
+	public Grid getScheduledEventsReport(List<String> searchKeys,
+			Collection<OrganisationUnit> 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<PatientAttribute> 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, statusEnrollment, min, max);
+	}
+
+	@Override
+	public Grid getTrackingEventsReport(Program program,
+			List<String> searchKeys, Collection<OrganisationUnit> 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<PatientAttribute> patientAttributes = program
+				.getAttributes();
+
+		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));
+		grid.addHeader(new GridHeader(i18n.getString("risk"), false, true));
+
+		return patientStore.getPatientEventReport(grid, searchKeys, orgunits,
+				followup, patientAttributes, statusEnrollment, null, null);
+	}
+
+	@Override
+	public int validatePatient(Patient patient, Program program) {
+		return patientStore.validate(patient, program);
+	}
+
+	@Override
+	public Collection<Patient> searchPatientsForMobile(String searchText,
+
+	int orgUnitId, int patientAttributeId) {
+
+		Set<Patient> patients = new HashSet<Patient>();
+
+		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<Patient> toRemoveList = new HashSet<Patient>();
+
+			for (Patient patient : patients) {
+
+				if (patient.getOrganisationUnit().getId() != orgUnitId) {
+					toRemoveList.add(patient);
+				}
+			}
+			patients.removeAll(toRemoveList);
+		}
+		return patients;
+	}
+
+	@Override
+	public Collection<Patient> getPatientsByAttributeValue(String searchText,
+			int patientAttributeId, Integer min, Integer max) {
+		return patientStore.getByPatientAttributeValue(searchText,
+				patientAttributeId, min, max);
+	}
 
 }

=== 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-23 14:18:27 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientStore.java	2014-01-24 07:23:04 +0000
@@ -77,717 +77,753 @@
  * @author Abyot Asalefew Gizaw
  */
 @Transactional
-public class HibernatePatientStore
-    extends HibernateIdentifiableObjectStore<Patient>
-    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<Patient> 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<Patient> 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<Patient> 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<Patient> 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<Patient> 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<Patient> search( List<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Collection<PatientAttribute> patientAttributes, Integer statusEnrollment, Integer min,
-        Integer max )
-    {
-        String sql = searchPatientSql( false, searchKeys, orgunits, followup, patientAttributes, statusEnrollment, min,
-            max );
-        Collection<Patient> patients = new HashSet<Patient>();
-        try
-        {
-            patients = jdbcTemplate.query( sql, new RowMapper<Patient>()
-            {
-                public Patient mapRow( ResultSet rs, int rowNum )
-                    throws SQLException
-                {
-                    return get( rs.getInt( 1 ) );
-                }
-            } );
-        }
-        catch ( Exception ex )
-        {
-            ex.printStackTrace();
-        }
-        return patients;
-    }
-
-    @Override
-    public List<Integer> getProgramStageInstances( List<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Collection<PatientAttribute> patientAttributes, Integer statusEnrollment, Integer min,
-        Integer max )
-    {
-        String sql = searchPatientSql( false, searchKeys, orgunits, followup, patientAttributes, statusEnrollment, min,
-            max );
-
-        List<Integer> programStageInstanceIds = new ArrayList<Integer>();
-        try
-        {
-            programStageInstanceIds = jdbcTemplate.query( sql, new RowMapper<Integer>()
-            {
-                public Integer mapRow( ResultSet rs, int rowNum )
-                    throws SQLException
-                {
-                    return rs.getInt( "programstageinstanceid" );
-                }
-            } );
-        }
-        catch ( Exception ex )
-        {
-            ex.printStackTrace();
-        }
-
-        return programStageInstanceIds;
-    }
-
-    public int countSearch( List<String> searchKeys, Collection<OrganisationUnit> orgunits, Boolean followup,
-        Integer statusEnrollment )
-    {
-        String sql = searchPatientSql( true, searchKeys, orgunits, followup, null, statusEnrollment, null, null );
-        return jdbcTemplate.queryForObject( sql, Integer.class );
-    }
-
-    @Override
-    public Grid getPatientEventReport( Grid grid, List<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Collection<PatientAttribute> patientAttributes, Integer statusEnrollment, Integer min,
-        Integer max )
-    {
-        String sql = searchPatientSql( false, searchKeys, orgunits, followup, patientAttributes, statusEnrollment, min,
-            max );
-
-        SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
-
-        GridUtils.addRows( grid, rowSet );
-
-        return grid;
-    }
-
-    @Override
-    @SuppressWarnings( "unchecked" )
-    public Collection<Patient> 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<Integer> 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.getAttributeValues() != null && patient.getAttributeValues().size() > 0 )
-        {
-            boolean hasUnique = false;
-
-            for ( PatientAttributeValue attributeValue : patient.getAttributeValues() )
-            {
-                PatientAttribute attribute = attributeValue.getPatientAttribute();
-
-                if ( attribute.getUnique() )
-                {
-                    hasUnique = true;
-                    break;
-                }
-            }
-
-            if ( hasUnique )
-            {
-                Criteria criteria = getCriteria();
-                criteria.createAlias( "attributeValues", "attributeValue" );
-                criteria.createAlias( "organisationUnit", "orgunit" );
-                criteria.createAlias( "programInstances", "programInstance" );
-                criteria.createAlias( "programInstance.program", "program" );
-
-                Disjunction disjunction = Restrictions.disjunction();
-
-                for ( PatientAttributeValue attributeValue : patient.getAttributeValues() )
-                {
-                    PatientAttribute attribute = attributeValue.getPatientAttribute();
-
-                    if ( attribute.getUnique() )
-                    {
-                        Conjunction conjunction = Restrictions.conjunction();
-                        conjunction.add( Restrictions.eq( "attributeValue.value", attributeValue.getValue() ) );
-                        conjunction.add( Restrictions.eq( "attributeValue.patientAttribute", attribute ) );
-
-                        if ( patient.getId() != 0 )
-                        {
-                            conjunction.add( Restrictions.ne( "id", patient.getId() ) );
-                        }
-
-                        if ( attribute.getValueType().equals( PatientAttribute.VALUE_TYPE_LOCAL_ID )
-                            && attribute.getOrgunitScope() )
-                        {
-                            conjunction.add( Restrictions.eq( "orgunit.id", patient.getOrganisationUnit().getId() ) );
-                        }
-
-                        if ( program != null && attribute.getValueType().equals( PatientAttribute.VALUE_TYPE_LOCAL_ID )
-                            && attribute.getProgramScope() )
-                        {
-                            conjunction.add( Restrictions.eq( "programInstance.program", program ) );
-                        }
-
-                        if ( attribute.getValueType().equals( PatientAttribute.VALUE_TYPE_LOCAL_ID )
-                            && attribute.getPeriodType() != null )
-                        {
-                            Date currentDate = new Date();
-                            Period period = attribute.getPeriodType().createPeriod( currentDate );
-                            conjunction.add( Restrictions.between( "programInstance.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<String> searchKeys, Collection<OrganisationUnit> orgunits,
-        Boolean followup, Collection<PatientAttribute> patientAttributes, Integer statusEnrollment, Integer min,
-        Integer max )
-    {
-        String selector = count ? "count(*) " : "* ";
-        String sql = "select " + selector + " from ( select distinct p.patientid,";
-
-        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 isSearchEvent = false;
-        boolean isPriorityEvent = false;
-        Collection<Integer> 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_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 = " ";
-        }
-
-        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<Integer> getOrgunitChildren( Collection<OrganisationUnit> orgunits )
-    {
-        Collection<Integer> orgUnitIds = new HashSet<Integer>();
-
-        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<Integer> getOrganisationUnitIds( Collection<OrganisationUnit> orgunits )
-    {
-        Collection<Integer> orgUnitIds = new HashSet<Integer>();
-
-        for ( OrganisationUnit orgUnit : orgunits )
-        {
-            orgUnitIds.add( orgUnit.getId() );
-        }
-
-        if ( orgUnitIds.size() == 0 )
-        {
-            orgUnitIds.add( 0 );
-        }
-
-        return orgUnitIds;
-    }
+public class HibernatePatientStore extends
+		HibernateIdentifiableObjectStore<Patient> 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<Patient> 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<Patient> 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<Patient> 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<Patient> 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<Patient> 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<Patient> search(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			Integer statusEnrollment, Integer min, Integer max) {
+		String sql = searchPatientSql(false, searchKeys, orgunits, followup,
+				patientAttributes, statusEnrollment, min, max);
+		Collection<Patient> patients = new HashSet<Patient>();
+		try {
+			patients = jdbcTemplate.query(sql, new RowMapper<Patient>() {
+				public Patient mapRow(ResultSet rs, int rowNum)
+						throws SQLException {
+					return get(rs.getInt(1));
+				}
+			});
+		} catch (Exception ex) {
+			ex.printStackTrace();
+		}
+		return patients;
+	}
+
+	@Override
+	public List<Integer> getProgramStageInstances(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			Integer statusEnrollment, Integer min, Integer max) {
+		String sql = searchPatientSql(false, searchKeys, orgunits, followup,
+				patientAttributes, statusEnrollment, min, max);
+
+		List<Integer> programStageInstanceIds = new ArrayList<Integer>();
+		try {
+			programStageInstanceIds = jdbcTemplate.query(sql,
+					new RowMapper<Integer>() {
+						public Integer mapRow(ResultSet rs, int rowNum)
+								throws SQLException {
+							return rs.getInt("programstageinstanceid");
+						}
+					});
+		} catch (Exception ex) {
+			ex.printStackTrace();
+		}
+
+		return programStageInstanceIds;
+	}
+
+	public int countSearch(List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Integer statusEnrollment) {
+		String sql = searchPatientSql(true, searchKeys, orgunits, followup,
+				null, statusEnrollment, null, null);
+		return jdbcTemplate.queryForObject(sql, Integer.class);
+	}
+
+	@Override
+	public Grid getPatientEventReport(Grid grid, List<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			Integer statusEnrollment, Integer min, Integer max) {
+		String sql = searchPatientSql(false, searchKeys, orgunits, followup,
+				patientAttributes, statusEnrollment, min, max);
+
+		SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql);
+
+		GridUtils.addRows(grid, rowSet);
+
+		return grid;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Collection<Patient> 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<Integer> 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.getAttributeValues() != null
+				&& patient.getAttributeValues().size() > 0) {
+			boolean hasUnique = false;
+
+			for (PatientAttributeValue attributeValue : patient
+					.getAttributeValues()) {
+				PatientAttribute attribute = attributeValue
+						.getPatientAttribute();
+
+				if (attribute.getUnique()) {
+					hasUnique = true;
+					break;
+				}
+			}
+
+			if (hasUnique) {
+				Criteria criteria = getCriteria();
+				criteria.createAlias("attributeValues", "attributeValue");
+				criteria.createAlias("organisationUnit", "orgunit");
+				criteria.createAlias("programInstances", "programInstance");
+				criteria.createAlias("programInstance.program", "program");
+
+				Disjunction disjunction = Restrictions.disjunction();
+
+				for (PatientAttributeValue attributeValue : patient
+						.getAttributeValues()) {
+					PatientAttribute attribute = attributeValue
+							.getPatientAttribute();
+
+					if (attribute.getUnique()) {
+						Conjunction conjunction = Restrictions.conjunction();
+						conjunction.add(Restrictions.eq("attributeValue.value",
+								attributeValue.getValue()));
+						conjunction.add(Restrictions.eq(
+								"attributeValue.patientAttribute", attribute));
+
+						if (patient.getId() != 0) {
+							conjunction.add(Restrictions.ne("id",
+									patient.getId()));
+						}
+
+						if (attribute.getValueType().equals(
+								PatientAttribute.VALUE_TYPE_LOCAL_ID)
+								&& attribute.getOrgunitScope()) {
+							conjunction.add(Restrictions.eq("orgunit.id",
+									patient.getOrganisationUnit().getId()));
+						}
+
+						if (program != null
+								&& attribute.getValueType().equals(
+										PatientAttribute.VALUE_TYPE_LOCAL_ID)
+								&& attribute.getProgramScope()) {
+							conjunction.add(Restrictions.eq(
+									"programInstance.program", program));
+						}
+
+						if (attribute.getValueType().equals(
+								PatientAttribute.VALUE_TYPE_LOCAL_ID)
+								&& attribute.getPeriodType() != null) {
+							Date currentDate = new Date();
+							Period period = attribute.getPeriodType()
+									.createPeriod(currentDate);
+							conjunction
+									.add(Restrictions.between(
+											"programInstance.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<String> searchKeys,
+			Collection<OrganisationUnit> orgunits, Boolean followup,
+			Collection<PatientAttribute> patientAttributes,
+			Integer statusEnrollment, Integer min, Integer max) {
+		String selector = count ? "count(*) " : "* ";
+		String sql = "select " + selector
+				+ " from ( select distinct p.patientid,";
+
+		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 isSearchEvent = false;
+		boolean isPriorityEvent = false;
+		Collection<Integer> 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_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 = " ";
+		}
+
+		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<Integer> getOrgunitChildren(
+			Collection<OrganisationUnit> orgunits) {
+		Collection<Integer> orgUnitIds = new HashSet<Integer>();
+
+		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<Integer> getOrganisationUnitIds(
+			Collection<OrganisationUnit> orgunits) {
+		Collection<Integer> orgUnitIds = new HashSet<Integer>();
+
+		for (OrganisationUnit orgUnit : orgunits) {
+			orgUnitIds.add(orgUnit.getId());
+		}
+
+		if (orgUnitIds.size() == 0) {
+			orgUnitIds.add(0);
+		}
+
+		return orgUnitIds;
+	}
+	
+	@SuppressWarnings({ "unchecked" })
+	@Override
+	public Collection<Patient> 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 order by pav.patient";
+
+		Query query = getQuery(hql);
+
+		query.setInteger("patientAttributeId", patientAttributeId);
+
+		if (min != null && max != null) {
+			query.setFirstResult(min).setMaxResults(max);
+		}
+
+		List<Patient> patients = new ArrayList<Patient>();
+		Collection<PatientAttributeValue> 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	2014-01-23 16:54:20 +0000
+++ dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/namebaseddataentry/action/FindBeneficiarytAction.java	2014-01-24 07:23:04 +0000
@@ -33,151 +33,140 @@
 import java.util.Set;
 
 import org.hisp.dhis.patient.Patient;
+import org.hisp.dhis.patient.PatientService;
 import org.hisp.dhis.patientattributevalue.PatientAttributeValue;
 
 import com.opensymphony.xwork2.Action;
 
-public class FindBeneficiarytAction
-    implements Action
-{
-    private static final String REDIRECT = "redirect";
-
-    // -------------------------------------------------------------------------
-    // Input & Output
-    // -------------------------------------------------------------------------
-
-    private Collection<Patient> patients;
-
-    public Collection<Patient> getPatients()
-    {
-        return patients;
-    }
-
-    public void setPatients( Collection<Patient> patients )
-    {
-        this.patients = patients;
-    }
-
-    private Set<PatientAttributeValue> pavSet;
-
-    public Set<PatientAttributeValue> getPavSet()
-    {
-        return pavSet;
-    }
-
-    public void setPavSet( Set<PatientAttributeValue> pavSet )
-    {
-        this.pavSet = pavSet;
-    }
-
-    private Set<PatientAttributeValue> patientAttributes;
-
-    public Set<PatientAttributeValue> getPatientAttributes()
-    {
-        return patientAttributes;
-    }
-
-    public void setPatientAttributes( Set<PatientAttributeValue> 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<PatientAttributeValue>();
-
-        for ( Patient p : patients )
-        {
-            pavSet.addAll( p.getAttributeValues() );
-        }
-
-        if ( patients.size() == 1 )
-        {
-            Patient patient = patients.iterator().next();
-            patientId = patient.getId();
-
-            return REDIRECT;
-        }
-        return SUCCESS;
-    }
+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<Patient> patients;
+
+	public Collection<Patient> getPatients() {
+		return patients;
+	}
+
+	public void setPatients(Collection<Patient> patients) {
+		this.patients = patients;
+	}
+
+	private Set<PatientAttributeValue> pavSet;
+
+	public Set<PatientAttributeValue> getPavSet() {
+		return pavSet;
+	}
+
+	public void setPavSet(Set<PatientAttributeValue> pavSet) {
+		this.pavSet = pavSet;
+	}
+
+	private Set<PatientAttributeValue> patientAttributes;
+
+	public Set<PatientAttributeValue> getPatientAttributes() {
+		return patientAttributes;
+	}
+
+	public void setPatientAttributes(
+			Set<PatientAttributeValue> 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<PatientAttributeValue>();
+
+		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/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml	2014-01-23 16:54:20 +0000
+++ dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml	2014-01-24 07:23:04 +0000
@@ -244,6 +244,7 @@
 		id="org.hisp.dhis.light.namebaseddataentry.action.FindBeneficiarytAction"
 		class="org.hisp.dhis.light.namebaseddataentry.action.FindBeneficiarytAction"
 		scope="prototype">
+		  <property name="patientService" ref="org.hisp.dhis.patient.PatientService" />
 	</bean>
 
 
@@ -260,8 +261,6 @@
 		<property name="relationshipTypeService"
 			ref="org.hisp.dhis.relationship.RelationshipTypeService" />
 		<property name="util" ref="org.hisp.dhis.light.utils.NamebasedUtils" />
-		<property name="patientIdentifierService"
-			ref="org.hisp.dhis.patient.PatientIdentifierService" />
 		<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
 		<property name="patientAttributeValueService"
 			ref="org.hisp.dhis.patientattributevalue.PatientAttributeValueService" />
@@ -343,8 +342,6 @@
 		id="org.hisp.dhis.light.beneficiaryregistration.action.RegisterBeneficiaryAction"
 		class="org.hisp.dhis.light.beneficiaryregistration.action.RegisterBeneficiaryAction"
 		scope="prototype">
-		<property name="patientIdentifierTypeService"
-			ref="org.hisp.dhis.patient.PatientIdentifierTypeService" />
 		<property name="patientAttributeService"
 			ref="org.hisp.dhis.patient.PatientAttributeService" />
 		<property name="programService" ref="org.hisp.dhis.program.ProgramService" />
@@ -358,14 +355,10 @@
 		<property name="organisationUnitService"
 			ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
 		<property name="patientService" ref="org.hisp.dhis.patient.PatientService" />
-		<property name="patientIdentifierTypeService"
-			ref="org.hisp.dhis.patient.PatientIdentifierTypeService" />
 		<property name="patientAttributeService"
 			ref="org.hisp.dhis.patient.PatientAttributeService" />
 		<property name="patientAttributeOptionService"
 			ref="org.hisp.dhis.patient.PatientAttributeOptionService" />
-		<property name="patientIdentifierService"
-			ref="org.hisp.dhis.patient.PatientIdentifierService" />
 		<property name="programService" ref="org.hisp.dhis.program.ProgramService" />
 	</bean>
 
@@ -424,8 +417,6 @@
 			ref="org.hisp.dhis.patient.PatientAttributeOptionService" />
 		<property name="patientAttributeService"
 			ref="org.hisp.dhis.patient.PatientAttributeService" />
-		<property name="patientIdentifierService"
-			ref="org.hisp.dhis.patient.PatientIdentifierService" />
 	</bean>
 
 	<!-- Single Event -->