Repository: opensrp/fhircore
Issue: [Quest/Malawi Core] Searching patient by unique identifier not working

**Describe the bug**
When searching for a patient by their unique identifier, the wrong patient is presented. Currently, we have a patient in the server called "Chimwemwe Phiri" who has an ART number "578". When you search for this patient by name, it works as expected. However, when you search by the ID, the patient "Allan Poe" is found.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to the patient register
2. Search 578
3. The patient "Allan Poe" appears instead of "Chimwemwe Phiri"

**Expected behavior**
When the ID, 578, is searched, the patient presented should be "Chimwemwe Phiri"

**Screenshots**
N/A

**Smartphone (please complete the following information):**
- Device: Samsung A12
- Android version: 11
- Build number: RP1A.200720.012.A127FXXU4AUK1
- Version: 30

**Additional context**
N/A



Changed files:
android/engine/src/test/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDaoTest.kt
android/engine/src/main/java/org/smartregister/fhircore/engine/util/extension/PatientExtension.kt
android/engine/src/test/java/org/smartregister/fhircore/engine/util/extension/PatientExtensionTest.kt
android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/register/PatientRegisterViewModel.kt
android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/models/RegisterViewData.kt
android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDao.kt
android/quest/src/main/java/org/smartregister/fhircore/quest/util/mappers/RegisterViewDataMapper.kt

diff --git a/android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDao.kt b/android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDao.kt
index edc0f8eb5..0b607f8bc 100644
--- a/android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDao.kt
+++ b/android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDao.kt
@@ -38,6 +38,8 @@ import org.smartregister.fhircore.engine.util.extension.extractAddress
 import org.smartregister.fhircore.engine.util.extension.extractGeneralPractitionerReference
 import org.smartregister.fhircore.engine.util.extension.extractHealthStatusFromMeta
 import org.smartregister.fhircore.engine.util.extension.extractName
+import org.smartregister.fhircore.engine.util.extension.extractOfficialIdentifier
+import org.smartregister.fhircore.engine.util.extension.extractSecondaryIdentifier
 import org.smartregister.fhircore.engine.util.extension.extractTelecom
 import org.smartregister.fhircore.engine.util.extension.toAgeDisplay
 
@@ -55,6 +57,11 @@ constructor(
       patient.hasGender() &&
       patient.meta.tag.none { it.code.equals(HAPI_MDM_TAG, true) }
 
+  fun hivPatientIdentifier(patient: Patient): String =
+    // would either be an ART or HCC number
+    patient.extractOfficialIdentifier()
+      ?: patient.extractSecondaryIdentifier() ?: patient.identifierFirstRep.value
+
   override suspend fun loadRegisterData(
     currentPage: Int,
     loadAll: Boolean,
@@ -73,7 +80,7 @@ constructor(
     return patients.filter(this::isValidPatient).map { patient ->
       RegisterData.HivRegisterData(
         logicalId = patient.logicalId,
-        identifier = patient.identifierFirstRep.value,
+        identifier = hivPatientIdentifier(patient),
         name = patient.extractName(),
         gender = patient.gender,
         age = patient.birthDate.toAgeDisplay(),
@@ -97,7 +104,7 @@ constructor(
       logicalId = patient.logicalId,
       birthdate = patient.birthDate,
       name = patient.extractName(),
-      identifier = patient.identifierFirstRep.value,
+      identifier = hivPatientIdentifier(patient),
       gender = patient.gender,
       age = patient.birthDate.toAgeDisplay(),
       address = patient.extractAddress(),
diff --git a/android/engine/src/main/java/org/smartregister/fhircore/engine/util/extension/PatientExtension.kt b/android/engine/src/main/java/org/smartregister/fhircore/engine/util/extension/PatientExtension.kt
index 0c76b96e4..b03993d71 100644
--- a/android/engine/src/main/java/org/smartregister/fhircore/engine/util/extension/PatientExtension.kt
+++ b/android/engine/src/main/java/org/smartregister/fhircore/engine/util/extension/PatientExtension.kt
@@ -209,6 +209,13 @@ fun Enumerations.AdministrativeGender.translateGender(context: Context) =
     else -> context.getString(R.string.unknown)
   }
 
+fun Patient.extractSecondaryIdentifier(): String? {
+  if (this.hasIdentifier()) {
+    return this.identifier.firstOrNull { it.use == Identifier.IdentifierUse.SECONDARY }?.value
+  }
+  return null
+}
+
 fun Patient.extractOfficialIdentifier(): String? =
   if (this.hasIdentifier())
     this.identifier.firstOrNull { it.use == Identifier.IdentifierUse.OFFICIAL }?.value
diff --git a/android/engine/src/test/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDaoTest.kt b/android/engine/src/test/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDaoTest.kt
index 91dfca15b..04cfaa8a3 100644
--- a/android/engine/src/test/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDaoTest.kt
+++ b/android/engine/src/test/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDaoTest.kt
@@ -31,6 +31,7 @@ import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.runTest
 import org.hl7.fhir.r4.model.CarePlan
 import org.hl7.fhir.r4.model.Enumerations
+import org.hl7.fhir.r4.model.Identifier
 import org.hl7.fhir.r4.model.Patient
 import org.hl7.fhir.r4.model.Resource
 import org.hl7.fhir.r4.model.ResourceType
@@ -169,6 +170,48 @@ class HivRegisterDaoTest : RobolectricTest() {
     assertEquals(Enumerations.AdministrativeGender.MALE, hivProfileData.gender)
   }
 
+  @Test
+  fun `test hiv patient identifier to be the 'official' identifier`() = runTest {
+    val identifierNumber = "123456"
+    val patient =
+      Patient().apply {
+        identifier.add(Identifier())
+
+        identifier.add(
+          Identifier().apply {
+            this.use = Identifier.IdentifierUse.OFFICIAL
+            this.value = identifierNumber
+          }
+        )
+
+        identifier.add(
+          Identifier().apply {
+            this.use = Identifier.IdentifierUse.SECONDARY
+            this.value = "149856"
+          }
+        )
+      }
+    assertEquals(identifierNumber, hivRegisterDao.hivPatientIdentifier(patient))
+  }
+
+  @Test
+  fun `test hiv patient identifier to be the 'secondary' identifier when no 'official' identifier found`() =
+      runTest {
+    val identifierNumber = "149856"
+    val patient =
+      Patient().apply {
+        identifier.add(Identifier())
+
+        identifier.add(
+          Identifier().apply {
+            this.use = Identifier.IdentifierUse.SECONDARY
+            this.value = identifierNumber
+          }
+        )
+      }
+    assertEquals(identifierNumber, hivRegisterDao.hivPatientIdentifier(patient))
+  }
+
   @Test
   fun testGetRegisterDataFilters() {
     assertNotNull(hivRegisterDao.getRegisterDataFilters("1234"))
diff --git a/android/engine/src/test/java/org/smartregister/fhircore/engine/util/extension/PatientExtensionTest.kt b/android/engine/src/test/java/org/smartregister/fhircore/engine/util/extension/PatientExtensionTest.kt
index fbb443565..7af161b35 100644
--- a/android/engine/src/test/java/org/smartregister/fhircore/engine/util/extension/PatientExtensionTest.kt
+++ b/android/engine/src/test/java/org/smartregister/fhircore/engine/util/extension/PatientExtensionTest.kt
@@ -25,6 +25,7 @@ import org.hl7.fhir.r4.model.DateTimeType
 import org.hl7.fhir.r4.model.Enumerations
 import org.hl7.fhir.r4.model.Extension
 import org.hl7.fhir.r4.model.HumanName
+import org.hl7.fhir.r4.model.Identifier
 import org.hl7.fhir.r4.model.Immunization
 import org.hl7.fhir.r4.model.Patient
 import org.hl7.fhir.r4.model.StringType
@@ -469,4 +470,20 @@ class PatientExtensionTest : RobolectricTest() {
     Assert.assertNotNull(patient.extractHealthStatusFromMeta(""))
     Assert.assertEquals(HealthStatus.DEFAULT, patient.extractHealthStatusFromMeta(""))
   }
+
+  @Test
+  fun testExtractSecondaryIdentifier() {
+    val patient = Patient()
+    Assert.assertNull(patient.extractSecondaryIdentifier())
+    val secondaryValue = "123456"
+    patient.apply {
+      identifier.add(
+        Identifier().apply {
+          this.use = Identifier.IdentifierUse.SECONDARY
+          this.value = secondaryValue
+        }
+      )
+    }
+    Assert.assertEquals(secondaryValue, patient.extractSecondaryIdentifier())
+  }
 }
diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/register/PatientRegisterViewModel.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/register/PatientRegisterViewModel.kt
index 69c08645c..19640304c 100644
--- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/register/PatientRegisterViewModel.kt
+++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/patient/register/PatientRegisterViewModel.kt
@@ -168,7 +168,7 @@ constructor(
         pagingData: PagingData<RegisterViewData> ->
         pagingData.filter {
           it.title.contains(event.searchText, ignoreCase = true) ||
-            it.logicalId.contains(event.searchText, ignoreCase = true)
+            it.identifier.contains(event.searchText, ignoreCase = true)
         }
       }
   }
diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/models/RegisterViewData.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/models/RegisterViewData.kt
index 460a2eb33..9ce4959a8 100644
--- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/models/RegisterViewData.kt
+++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/models/RegisterViewData.kt
@@ -37,5 +37,6 @@ data class RegisterViewData(
   val serviceButtonBorderColor: Color = InfoColor,
   val borderedServiceButton: Boolean = false,
   val showDivider: Boolean = false,
-  val showServiceButton: Boolean = true
+  val showServiceButton: Boolean = true,
+  val identifier: String = ""
 )
diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/util/mappers/RegisterViewDataMapper.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/util/mappers/RegisterViewDataMapper.kt
index b7e79f27b..07a81b379 100644
--- a/android/quest/src/main/java/org/smartregister/fhircore/quest/util/mappers/RegisterViewDataMapper.kt
+++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/util/mappers/RegisterViewDataMapper.kt
@@ -95,7 +95,8 @@ class RegisterViewDataMapper @Inject constructor(@ApplicationContext val context
         RegisterViewData(
           logicalId = inputModel.logicalId,
           title = listOf(inputModel.name, inputModel.age).joinToString(", "),
-          subtitle = inputModel.gender.translateGender(context).capitalizeFirstLetter()
+          subtitle = inputModel.gender.translateGender(context).capitalizeFirstLetter(),
+          identifier = inputModel.identifier ?: ""
         )
       is RegisterData.AppointmentRegisterData ->
         RegisterViewData(