Skip to content

Commit ae72def

Browse files
committed
Move side menu counts to a 'Counters' screen
1 parent 6cdf69d commit ae72def

32 files changed

+546
-271
lines changed

android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/AppRegisterRepository.kt

+4-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package org.smartregister.fhircore.engine.data.local.register
1818

1919
import com.google.android.fhir.FhirEngine
2020
import javax.inject.Inject
21+
import kotlinx.coroutines.flow.Flow
22+
import kotlinx.coroutines.flow.emptyFlow
2123
import kotlinx.coroutines.withContext
2224
import org.hl7.fhir.r4.model.Patient
2325
import org.hl7.fhir.r4.model.Resource
@@ -129,7 +131,6 @@ constructor(
129131
}
130132

131133
override suspend fun countRegisterFiltered(
132-
appFeatureName: String?,
133134
healthModule: HealthModule,
134135
filters: RegisterFilter,
135136
): Long {
@@ -151,20 +152,18 @@ constructor(
151152
}
152153

153154
registerDaoFactory.registerDaoMap[healthModule]?.countRegisterFiltered(
154-
appFeatureName,
155155
filters,
156156
) ?: 0
157157
}
158158
}
159159
}
160160

161161
override suspend fun countRegisterData(
162-
appFeatureName: String?,
163162
healthModule: HealthModule,
164-
): Long =
163+
): Flow<Long> =
165164
withContext(dispatcherProvider.io()) {
166165
tracer.traceSuspend("${healthModule.name.camelCase()}.countRegisterData") {
167-
registerDaoFactory.registerDaoMap[healthModule]?.countRegisterData(appFeatureName) ?: 0
166+
registerDaoFactory.registerDaoMap[healthModule]?.countRegisterData() ?: emptyFlow()
168167
}
169168
}
170169

android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/AncPatientRegisterDao.kt

+3-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import com.google.android.fhir.FhirEngine
2020
import com.google.android.fhir.datacapture.extensions.logicalId
2121
import com.google.android.fhir.get
2222
import com.google.android.fhir.search.Order
23-
import com.google.android.fhir.search.count
2423
import com.google.android.fhir.search.search
2524
import javax.inject.Inject
2625
import javax.inject.Singleton
@@ -66,10 +65,9 @@ constructor(
6665
.search<Condition> {
6766
// [].forEach { filterBy(it) }
6867
sort(Patient.NAME, Order.ASCENDING)
69-
count =
70-
if (loadAll) {
71-
countRegisterData(appFeatureName).toInt()
72-
} else PaginationConstant.DEFAULT_PAGE_SIZE + PaginationConstant.EXTRA_ITEM_COUNT
68+
if (!loadAll) {
69+
count = PaginationConstant.DEFAULT_PAGE_SIZE + PaginationConstant.EXTRA_ITEM_COUNT
70+
}
7371
from = currentPage * PaginationConstant.DEFAULT_PAGE_SIZE
7472
}
7573
.map { it.resource }
@@ -143,7 +141,6 @@ constructor(
143141
)
144142
}
145143

146-
override suspend fun countRegisterData(appFeatureName: String?) = 0L
147144
// fhirEngine.count<Condition> { getRegisterDataFilters().forEach { filterBy(it) } }
148145

149146
private fun getVisitStatus(carePlans: List<CarePlan>): VisitStatus {

android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/AppointmentRegisterDao.kt

+24-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import java.util.Calendar
2727
import java.util.Date
2828
import javax.inject.Inject
2929
import javax.inject.Singleton
30+
import kotlinx.coroutines.flow.Flow
31+
import kotlinx.coroutines.flow.flow
3032
import org.hl7.fhir.r4.model.Appointment
3133
import org.hl7.fhir.r4.model.CodeableConcept
3234
import org.hl7.fhir.r4.model.DateTimeType
@@ -85,16 +87,35 @@ constructor(
8587
private fun applicationConfiguration(): ApplicationConfiguration =
8688
configurationRegistry.getAppConfigs()
8789

88-
override suspend fun countRegisterData(appFeatureName: String?): Long {
90+
override suspend fun countRegisterData(): Flow<Long> {
91+
var counter = 0L
92+
var offset = 0
93+
val pageCount = 100
8994
val dateOfAppointment = Calendar.getInstance().time
90-
return fhirEngine
95+
fhirEngine
9196
.search<Appointment> { genericFilter(dateOfAppointment) }
9297
.map { it.resource }
9398
.count { isAppointmentValid(it) }
9499
.toLong()
100+
101+
return flow {
102+
do {
103+
val appointments =
104+
fhirEngine.search<Appointment> {
105+
genericFilter(dateOfAppointment)
106+
from = offset
107+
count = pageCount
108+
}
109+
offset += appointments.size
110+
val validAppointmentCount =
111+
appointments.map { it.resource }.count { isAppointmentValid(it) }
112+
counter += validAppointmentCount
113+
emit(counter)
114+
} while (appointments.isNotEmpty())
115+
}
95116
}
96117

97-
override suspend fun countRegisterFiltered(appFeatureName: String?, filters: RegisterFilter) =
118+
override suspend fun countRegisterFiltered(filters: RegisterFilter): Long =
98119
searchAppointments(filters, loadAll = true).count().toLong()
99120

100121
private suspend fun patientCategoryMatches(

android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/FamilyRegisterDao.kt

+16-11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import com.google.android.fhir.search.search
2323
import java.util.UUID
2424
import javax.inject.Inject
2525
import javax.inject.Singleton
26+
import kotlinx.coroutines.flow.Flow
27+
import kotlinx.coroutines.flow.flow
2628
import org.hl7.fhir.r4.model.CarePlan
2729
import org.hl7.fhir.r4.model.Condition
2830
import org.hl7.fhir.r4.model.Flag
@@ -76,10 +78,9 @@ constructor(
7678
val families =
7779
fhirEngine.search<Group> {
7880
getRegisterDataFilters(FAMILY.name).forEach { filterBy(it) }
79-
count =
80-
if (loadAll) {
81-
countRegisterData(appFeatureName).toInt()
82-
} else PaginationConstant.DEFAULT_PAGE_SIZE + PaginationConstant.EXTRA_ITEM_COUNT
81+
if (!loadAll) {
82+
count = PaginationConstant.DEFAULT_PAGE_SIZE + PaginationConstant.EXTRA_ITEM_COUNT
83+
}
8384
from = currentPage * PaginationConstant.DEFAULT_PAGE_SIZE
8485
}
8586

@@ -140,14 +141,18 @@ constructor(
140141
)
141142
}
142143

143-
override suspend fun countRegisterData(appFeatureName: String?): Long {
144+
override suspend fun countRegisterData(): Flow<Long> {
144145
// TODO fix this workaround for groups count
145-
return fhirEngine
146-
.search<Group> { getRegisterDataFilters(FAMILY.name).forEach { filterBy(it) } }
147-
.map { it.resource }
148-
.filter { it.active && !it.name.isNullOrEmpty() }
149-
.size
150-
.toLong()
146+
return flow {
147+
val count =
148+
fhirEngine
149+
.search<Group> { getRegisterDataFilters(FAMILY.name).forEach { filterBy(it) } }
150+
.map { it.resource }
151+
.filter { it.active && !it.name.isNullOrEmpty() }
152+
.size
153+
.toLong()
154+
emit(count)
155+
}
151156
}
152157

153158
private suspend fun loadFamilyHead(family: Group) =

android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/HivRegisterDao.kt

+44-11
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import com.google.android.fhir.search.search
2929
import javax.inject.Inject
3030
import javax.inject.Provider
3131
import javax.inject.Singleton
32+
import kotlinx.coroutines.flow.Flow
33+
import kotlinx.coroutines.flow.flow
3234
import org.hl7.fhir.r4.model.CodeType
3335
import org.hl7.fhir.r4.model.CodeableConcept
3436
import org.hl7.fhir.r4.model.Coding
@@ -103,6 +105,15 @@ constructor(
103105

104106
private suspend fun searchRegisterData(block: Search.() -> Unit = {}) =
105107
fhirEngine.search<Patient> {
108+
filter(Patient.ACTIVE, { value = of(true) })
109+
filter(Patient.DECEASED, { value = of(false) })
110+
filter(
111+
Patient.GENDER,
112+
{ value = of("male") },
113+
{ value = of("female") },
114+
operation = Operation.OR,
115+
)
116+
106117
revInclude<Condition>(Condition.SUBJECT) {
107118
filter(
108119
Condition.CODE,
@@ -169,7 +180,6 @@ constructor(
169180
appFeatureName: String?,
170181
): List<RegisterData> {
171182
val patients = searchRegisterData {
172-
filter(Patient.ACTIVE, { value = of(true) })
173183
if (!loadAll) {
174184
count = PaginationConstant.DEFAULT_PAGE_SIZE + PaginationConstant.EXTRA_ITEM_COUNT
175185
}
@@ -239,16 +249,39 @@ constructor(
239249
)
240250
}
241251

242-
override suspend fun countRegisterData(appFeatureName: String?): Long {
243-
return fhirEngine
244-
.search<Patient> { filter(Patient.ACTIVE, { value = of(true) }) }
245-
.map { it.resource }
246-
.filter(this::isValidPatient)
247-
.filterNot {
248-
it.extractHealthStatusFromMeta(patientTypeMetaTagCodingSystem) == HealthStatus.DEFAULT
249-
}
250-
.size
251-
.toLong()
252+
override suspend fun countRegisterData(): Flow<Long> {
253+
var counter = 0L
254+
var offset = 0
255+
val pageCount = 100
256+
257+
return flow {
258+
do {
259+
val patients =
260+
fhirEngine.search<Patient> {
261+
filter(Patient.ACTIVE, { value = of(true) })
262+
filter(Patient.DECEASED, { value = of(false) })
263+
filter(
264+
Patient.GENDER,
265+
{ value = of("male") },
266+
{ value = of("female") },
267+
operation = Operation.OR,
268+
)
269+
from = offset
270+
count = pageCount
271+
}
272+
offset += patients.size
273+
val validPatientCount =
274+
patients
275+
.map { it.resource }
276+
.filter(this@HivRegisterDao::isValidPatient)
277+
.filterNot {
278+
it.extractHealthStatusFromMeta(patientTypeMetaTagCodingSystem) == HealthStatus.DEFAULT
279+
}
280+
.size
281+
counter += validPatientCount
282+
emit(counter)
283+
} while (patients.isNotEmpty())
284+
}
252285
}
253286

254287
override suspend fun loadPatient(patientId: String) = fhirEngine.loadResource<Patient>(patientId)

android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/register/dao/TracingRegisterDao.kt

+25-13
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ import com.google.android.fhir.search.search
3232
import java.time.LocalDate
3333
import java.time.ZoneId
3434
import java.util.Date
35+
import kotlinx.coroutines.flow.Flow
36+
import kotlinx.coroutines.flow.flow
3537
import org.hl7.fhir.r4.model.Appointment
3638
import org.hl7.fhir.r4.model.CarePlan
39+
import org.hl7.fhir.r4.model.CodeType
3740
import org.hl7.fhir.r4.model.Coding
3841
import org.hl7.fhir.r4.model.DateTimeType
3942
import org.hl7.fhir.r4.model.ListResource
@@ -104,9 +107,7 @@ abstract class TracingRegisterDao(
104107
private val filtersForValidTask: BaseSearch.() -> Unit = {
105108
filter(
106109
TokenClientParam("_tag"),
107-
{ value = of(tracingCoding) },
108-
{ value = of(alternateTracingCoding.value) },
109-
operation = Operation.OR,
110+
{ value = of(CodeType(tracingCoding.code)) },
110111
)
111112
filter(
112113
Task.STATUS,
@@ -401,19 +402,30 @@ abstract class TracingRegisterDao(
401402
}
402403
.map { defaultRepository.loadResource(it.other) }
403404

404-
override suspend fun countRegisterFiltered(
405-
appFeatureName: String?,
406-
filters: RegisterFilter,
407-
): Long {
405+
override suspend fun countRegisterFiltered(filters: RegisterFilter): Long {
408406
return searchRegister(filters, loadAll = true).count().toLong()
409407
}
410408

411-
override suspend fun countRegisterData(appFeatureName: String?): Long {
412-
val patients =
413-
fhirEngine
414-
.search<Patient> { has<Task>(Task.SUBJECT) { filtersForValidTask() } }
415-
.map { it.resource }
416-
return patients.count { validTasks(it).any() }.toLong()
409+
override suspend fun countRegisterData(): Flow<Long> {
410+
var counter = 0L
411+
var offset = 0
412+
val pageCount = 100
413+
414+
return flow {
415+
do {
416+
val tracingPatients =
417+
fhirEngine.search<Patient> {
418+
has<Task>(Task.SUBJECT) { filtersForValidTask() }
419+
from = offset
420+
count = pageCount
421+
}
422+
offset += tracingPatients.size
423+
val validTracingPatientsCount =
424+
tracingPatients.map { it.resource }.count { validTasks(it).any() }.toLong()
425+
counter += validTracingPatientsCount
426+
emit(counter)
427+
} while (tracingPatients.isNotEmpty())
428+
}
417429
}
418430

419431
private fun applicationConfiguration(): ApplicationConfiguration =

android/engine/src/main/java/org/smartregister/fhircore/engine/domain/model/SideMenuOption.kt

+2-5
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ data class SideMenuOption(
3434
val healthModule: HealthModule = HealthModule.DEFAULT,
3535
val iconResource: Int,
3636
val titleResource: Int,
37-
val count: Long = SIDE_MENU_COUNT_NOT_SET,
38-
val getCount: suspend () -> Long = { count },
39-
val showCount: Boolean = true,
37+
val count: Int = 0,
38+
val showCount: Boolean = false,
4039
)
41-
42-
const val SIDE_MENU_COUNT_NOT_SET = -1L

android/engine/src/main/java/org/smartregister/fhircore/engine/domain/repository/RegisterDao.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.smartregister.fhircore.engine.domain.repository
1818

19+
import kotlinx.coroutines.flow.Flow
20+
import kotlinx.coroutines.flow.emptyFlow
1921
import org.smartregister.fhircore.engine.data.local.RegisterFilter
2022
import org.smartregister.fhircore.engine.domain.model.ProfileData
2123
import org.smartregister.fhircore.engine.domain.model.RegisterData
@@ -45,11 +47,11 @@ interface RegisterDao {
4547
TODO("default")
4648
}
4749

48-
suspend fun countRegisterFiltered(appFeatureName: String? = null, filters: RegisterFilter): Long {
50+
suspend fun countRegisterFiltered(filters: RegisterFilter): Long {
4951
TODO("default")
5052
}
5153

52-
suspend fun countRegisterData(appFeatureName: String?): Long = 0
54+
suspend fun countRegisterData(): Flow<Long> = emptyFlow()
5355

5456
suspend fun loadProfileData(appFeatureName: String?, resourceId: String): ProfileData? = null
5557
}

android/engine/src/main/java/org/smartregister/fhircore/engine/domain/repository/RegisterRepository.kt

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.smartregister.fhircore.engine.domain.repository
1818

19+
import kotlinx.coroutines.flow.Flow
1920
import org.smartregister.fhircore.engine.appfeature.model.HealthModule
2021
import org.smartregister.fhircore.engine.data.local.RegisterFilter
2122
import org.smartregister.fhircore.engine.domain.model.ProfileData
@@ -39,15 +40,13 @@ interface RegisterRepository {
3940
): List<RegisterData>
4041

4142
suspend fun countRegisterFiltered(
42-
appFeatureName: String? = null,
4343
healthModule: HealthModule,
4444
filters: RegisterFilter,
4545
): Long
4646

4747
suspend fun countRegisterData(
48-
appFeatureName: String? = null,
4948
healthModule: HealthModule = HealthModule.DEFAULT,
50-
): Long
49+
): Flow<Long>
5150

5251
suspend fun loadPatientProfileData(
5352
appFeatureName: String? = null,

android/engine/src/main/java/org/smartregister/fhircore/engine/sync/OnSyncListener.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import com.google.android.fhir.sync.SyncJobStatus
2222
* An interface the exposes a callback method [onSync] which accepts an application level FHIR Sync
2323
* [State].
2424
*/
25-
interface OnSyncListener {
25+
fun interface OnSyncListener {
2626
/** Callback method invoked to handle sync [state] */
2727
fun onSync(state: SyncJobStatus)
2828
}

android/engine/src/main/java/org/smartregister/fhircore/engine/sync/SyncBroadcaster.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ constructor(
121121
is SyncJobStatus.Failed,
122122
is SyncJobStatus.Succeeded, -> {
123123
if (syncJobStatus is SyncJobStatus.Failed) {
124-
syncJobStatus.exceptions.forEachIndexed { _, resourceSyncException ->
124+
syncJobStatus.exceptions?.forEachIndexed { _, resourceSyncException ->
125125
Firebase.crashlytics.recordException(resourceSyncException.exception)
126126
}
127127
}

0 commit comments

Comments
 (0)