Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f4561d0
set up encounter payload structure
jabahum Jul 1, 2025
0f9f1c5
add compiler fix
jabahum Jul 1, 2025
e33bc65
feat: add Firebase Crashlytics
jabahum Jul 1, 2025
d1cb992
refactor: improve OpenMRS concept mapping for forms
jabahum Jul 2, 2025
1ad5b4b
Update encounter handling and state
jabahum Jul 2, 2025
5e456f7
feat: save encounters locally
jabahum Jul 2, 2025
89aa775
Refactor: Update Kotlin JVM target configuration and dependencies
jabahum Jul 2, 2025
a94bc44
Refactor: Move PatientMapper to PatientExtensions and update sync logic
jabahum Jul 2, 2025
cb3e0a9
feat: implement background sync for encounters and patients
jabahum Jul 2, 2025
9f479fa
chore: update Firebase and Hilt dependencies
jabahum Jul 2, 2025
34f7058
Refactor: Simplify patient entity creation
jabahum Jul 2, 2025
c611f6c
Refactor: Align Encounter and Visit models with OpenMRS structure
jabahum Jul 3, 2025
5ce1433
Update EncounterCard to use `obs` instead of `observations`
jabahum Jul 3, 2025
ced9e0e
feat: support repeating groups in forms
jabahum Jul 3, 2025
f9af5d5
Update local encounter handling and navigation
jabahum Jul 3, 2025
55ab55f
Refactor: Introduce SyncUiState and SyncEvent for SyncViewModel
jabahum Jul 3, 2025
7d488f6
Refactor: Improve Sync and Settings UI, update data fetching, and add…
jabahum Jul 4, 2025
0d9bc2e
Refactor: Replace VisitSummary with VisitEntity and update related co…
jabahum Jul 4, 2025
e176e90
feat: Implement "Start Visit" functionality and dialog
jabahum Jul 4, 2025
3ebe77c
Refactor: Improve Start Visit Dialog and display server version
jabahum Jul 4, 2025
a83d214
Refactor: Enhance PatientCard UI and move filtering to MainScreen
jabahum Jul 4, 2025
c17730f
feat: display most recent visit and enhance visit details
jabahum Jul 5, 2025
ce3c045
feat: Retrieve encounters by patient and visit ID
jabahum Jul 5, 2025
400ef0e
feat: Enhance visit and encounter handling in forms and worklist
jabahum Jul 5, 2025
cd99cb5
Refactor: Enhance Vitals data model and UI
jabahum Jul 5, 2025
6bcff07
Refactor: Optimize visit data loading and display
jabahum Jul 5, 2025
3d97a0b
feat: Integrate Vitals Recording into Patient Workflow
jabahum Jul 6, 2025
6901358
Refactor: Enhance vitals handling in WorklistViewModel and PatientDet…
jabahum Jul 6, 2025
6d47275
Refactor: Optimize data loading and remove redundant calls
jabahum Jul 7, 2025
19f39c8
Fix: Handle potential date parsing errors in `PatientDetailsScreen`
jabahum Jul 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@ android {
)
}

kotlinOptions {
jvmTarget = "11"
}

kotlin {
jvmToolchain(11)
Expand All @@ -111,6 +108,12 @@ android {
hilt {
enableAggregatingTask = false
}

configurations.all {
resolutionStrategy {
force("com.google.guava:guava:32.1.3-android")
}
}
}

dependencies {
Expand Down Expand Up @@ -167,7 +170,13 @@ dependencies {
// firebase
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
implementation(libs.google.firebase.analytics)
implementation(libs.firebase.crashlytics)


// work
implementation(libs.hilt.work)
implementation(libs.hilt.work.compiler)
implementation(libs.work.runtime.ktx)

testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
package com.lyecdevelopers.ugandaemrmobile

import android.app.Application
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import com.lyecdevelopers.core.utils.AppLogger
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject

@HiltAndroidApp
class UgandaEMRMobile : Application() {
class UgandaEMRMobile : Application(), Configuration.Provider {

@Inject
lateinit var workerFactory: HiltWorkerFactory

override fun onCreate() {
super.onCreate()
AppLogger.init()
}

override val workManagerConfiguration: Configuration
get() = Configuration.Builder().setWorkerFactory(workerFactory).build()
}





15 changes: 10 additions & 5 deletions auth/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ android {
targetCompatibility = JavaVersion.VERSION_11
isCoreLibraryDesugaringEnabled = true
}
kotlinOptions {
jvmTarget = "11"
}

packaging { resources.excludes.addAll(listOf("META-INF/ASL-2.0.txt", "META-INF/LGPL-3.0.txt")) }

hilt {
enableAggregatingTask = false
}

kotlin {
jvmToolchain(11)
}
}

dependencies {
Expand All @@ -65,13 +67,11 @@ dependencies {
implementation(libs.material.icons.extended)
implementation(libs.androidx.appcompat)


//fhir
implementation(libs.android.fhir.engine)
implementation(libs.android.fhir.sdc)
coreLibraryDesugaring(libs.desugar.jdk.libs)


// Hilt
implementation(libs.hilt.android)
ksp(libs.hilt.compiler)
Expand All @@ -95,6 +95,11 @@ dependencies {
// logging
implementation(libs.timber)

// firebase
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
implementation(libs.firebase.crashlytics)

// Optional: for previewing Composables
debugImplementation(libs.androidx.ui.tooling)

Expand Down
4 changes: 2 additions & 2 deletions core-navigation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ android {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
kotlin {
jvmToolchain(11)
}
}

Expand Down
11 changes: 6 additions & 5 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,16 @@ android {

kotlinOptions {
jvmTarget = "11"
freeCompilerArgs = listOf("-XXLanguage:+PropertyParamAnnotationDefaultTargetMode")
}

hilt {
enableAggregatingTask = false
}

kotlin {
jvmToolchain(11)
}
}

dependencies {
Expand All @@ -81,16 +86,12 @@ dependencies {
implementation(libs.androidx.paging.common.android)
implementation(libs.androidx.appcompat)



// fhir
implementation(libs.android.fhir.engine)
implementation(libs.android.fhir.sdc)
implementation(libs.androidx.constraintlayout)
coreLibraryDesugaring(libs.desugar.jdk.libs)



// Hilt
implementation(libs.hilt.android)
implementation(libs.androidx.datastore.preferences.core.android)
Expand Down Expand Up @@ -125,7 +126,7 @@ dependencies {
// firebase
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
implementation(libs.google.firebase.analytics)
implementation(libs.firebase.crashlytics)


// Optional: for previewing Composables
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.lyecdevelopers.core.data.local.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.lyecdevelopers.core.data.local.entity.EncounterEntity
import kotlinx.coroutines.flow.Flow


@Dao
interface EncounterDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(encounter: EncounterEntity)

@Query("SELECT * FROM encounters WHERE synced = 0")
suspend fun getUnsynced(): List<EncounterEntity>

@Update
suspend fun update(encounter: EncounterEntity): Int

@Query("SELECT COUNT(*) FROM encounters")
fun getEncountersCount(): Flow<Int>
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.lyecdevelopers.core.data.local.entity.FormEntity
import kotlinx.coroutines.flow.Flow

@Dao
interface FormDao {
Expand All @@ -28,6 +29,6 @@ interface FormDao {
suspend fun deleteFormById(uuid: String)

@Query("SELECT COUNT(*) FROM forms")
suspend fun getFormCount(): Int
fun getFormCount(): Flow<Int>
}

Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ interface PatientDao {
suspend fun insertAll(patients: List<PatientEntity>)

@Update
suspend fun updatePatient(patient: PatientEntity)
suspend fun updatePatient(patient: PatientEntity): Int

@Delete
suspend fun deletePatient(patient: PatientEntity)
Expand All @@ -87,5 +87,12 @@ interface PatientDao {

@Query("DELETE FROM patients")
suspend fun clearAll()

@Query("SELECT * FROM patients WHERE synced = 0")
suspend fun getUnsyncedPatients(): List<PatientEntity>

@Query("SELECT COUNT(*) FROM patients")
fun getPatientsCount(): Flow<Int>

}

Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import com.lyecdevelopers.core.data.local.entity.EncounterEntity
import com.lyecdevelopers.core.data.local.entity.VisitEntity
import com.lyecdevelopers.core.data.local.entity.VitalsEntity
import com.lyecdevelopers.core.model.VisitStatus
import com.lyecdevelopers.core.model.VisitWithDetails

@Dao
interface VisitDao {

// ➕ Add a single visit
// ➕ Insert a single visit
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertVisit(visit: VisitEntity)

// ➕ Add multiple visits (e.g., from sync)
// ➕ Insert multiple visits (e.g., from sync)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(visits: List<VisitEntity>)

Expand All @@ -38,5 +42,37 @@ interface VisitDao {
// 🔍 Get unsynced or pending visits (for syncing)
@Query("SELECT * FROM visits WHERE status = :status")
suspend fun getVisitsByStatus(status: VisitStatus): List<VisitEntity>

// ➕ Insert vitals
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertVitals(vitals: VitalsEntity)

// ➕ Insert encounters
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertEncounters(encounters: List<EncounterEntity>)

// 🧩 Get visit WITH related details (encounters + vitals)
@Transaction
@Query("SELECT * FROM visits WHERE patientId = :patientId")
suspend fun getVisitDetailsForPatient(patientId: String): List<VisitWithDetails>


// get most recent visit by date
@Query("SELECT * FROM visits WHERE patientId = :patientId ORDER BY scheduledTime DESC LIMIT 1")
suspend fun getMostRecentVisitForPatient(patientId: String): VisitWithDetails

// get encounter by patient id and visit id
@Query("SELECT * FROM encounters WHERE patientUuid = :patientId AND visitUuid = :visitId")
suspend fun getEncountersByPatientIdAndVisitId(
patientId: String,
visitId: String,
): List<EncounterEntity>

// get all visits with details
@Transaction
@Query("SELECT * FROM visits")
suspend fun getAllVisitsWithDetails(): List<VisitWithDetails>

}


This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.lyecdevelopers.core.data.local.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import com.lyecdevelopers.core.data.local.entity.VitalsEntity
import kotlinx.coroutines.flow.Flow

@Dao
interface VitalsDao {

/**
* Get a single vitals record for a specific visit.
* Returns null if no vitals recorded for that visit.
*/
@Transaction
@Query("SELECT * FROM vitals WHERE visitUuid = :visitUuid LIMIT 1")
fun getVitalsByVisit(visitUuid: String): Flow<VitalsEntity?>

/**
* Get all vitals ever recorded for a specific patient,
* newest first.
* Reactive flow for UI.
*/

@Transaction
@Query("SELECT * FROM vitals WHERE patientUuid = :patientUuid ORDER BY dateRecorded DESC")
fun getVitalsForPatient(patientUuid: String): Flow<List<VitalsEntity>>

/**
* Insert a new vitals record.
* Replace on conflict.
*/
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertVitals(vitals: VitalsEntity)


/**
* Delete a specific vitals record by ID.
*/
@Transaction
@Query("DELETE FROM vitals WHERE id = :vitalsId")
suspend fun deleteVitals(vitalsId: String)

/**
* Delete all vitals for a patient.
*/
@Transaction
@Query("DELETE FROM vitals WHERE patientUuid = :patientUuid")
suspend fun deleteVitalsForPatient(patientUuid: String)
}
Loading
Loading