Skip to content

Commit

Permalink
Fixed AddMedicine screen.
Browse files Browse the repository at this point in the history
Fixed some location permission logic.
Started modifying Room database and queries to show most appropriate data.
  • Loading branch information
Nyckoka committed May 23, 2024
1 parent f211959 commit 3b2eb37
Show file tree
Hide file tree
Showing 18 changed files with 314 additions and 227 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ data class MedicineWithClosestPharmacy(
val name: String,
val description: String,
val boxPhotoUrl: String,
val closestPharmacy: Long?
val closestPharmacyId: Long?,
val closestPharmacyName: String?
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ interface MedicineDao {
@Upsert
suspend fun upsertMedicine(medicine: MedicineEntity)

@Upsert(entity = MedicineEntity::class)
suspend fun upsertBaseMedicines(medicines: List<MedicineBaseEntity>)

data class MedicineBaseEntity(
val medicineId: Long,
val name: String,
val description: String,
val boxPhotoUrl: String
)

@Upsert
suspend fun upsertPharmacyMedicineList(pharmacyMedicineList: List<PharmacyMedicineEntity>)

Expand All @@ -23,22 +33,32 @@ interface MedicineDao {
notificationsActive: Boolean
)

@Query(
"""
SELECT medicines.medicineId, medicines.name, medicines.description, medicines.boxPhotoUrl, medicines.closestPharmacy, medicines.notificationsActive, pharmacy_medicine.stock
FROM medicines
INNER JOIN pharmacy_medicine ON medicines.medicineId = pharmacy_medicine.medicineId
WHERE pharmacy_medicine.pharmacyId = :pharmacyId
"""
)
suspend fun getPharmacyMedicineByPharmacyId(pharmacyId: Long): List<PharmacyMedicineFlatEntity>

@Query("SELECT * FROM medicines ORDER BY medicineId ASC")
fun pagingSource(): PagingSource<Int, MedicineEntity>

@Query("SELECT * FROM medicines WHERE name LIKE :query")
fun pagingSource(query: String): PagingSource<Int, MedicineEntity>

@Query(
"""
SELECT medicines.medicineId, medicines.name, medicines.description, medicines.boxPhotoUrl,
pharmacy_medicine.pharmacyId AS closestPharmacyId, pharmacies.name AS closestPharmacyName
FROM medicines
LEFT JOIN pharmacy_medicine ON medicines.medicineId = pharmacy_medicine.medicineId
INNER JOIN pharmacies ON pharmacy_medicine.pharmacyId = pharmacies.pharmacyId
WHERE pharmacy_medicine.pharmacyId = (
SELECT pharmacyId FROM pharmacies
ORDER BY (ABS(pharmacies.latitude - :latitude) + ABS(pharmacies.longitude - :longitude)) ASC
LIMIT 1
)
ORDER BY medicines.medicineId ASC
"""
)
fun medicineWithClosestPharmacyPagingSource(
latitude: Double,
longitude: Double
): PagingSource<Int, MedicineWithClosestPharmacyEntity>

@Query(
"""
SELECT * FROM medicines
Expand All @@ -55,6 +75,16 @@ interface MedicineDao {
@Query("SELECT * FROM medicines WHERE medicineId = :medicineId")
suspend fun getMedicineById(medicineId: Long): MedicineEntity

@Query(
"""
SELECT medicines.medicineId, medicines.name, medicines.description, medicines.boxPhotoUrl, medicines.notificationsActive, pharmacy_medicine.stock
FROM medicines
INNER JOIN pharmacy_medicine ON medicines.medicineId = pharmacy_medicine.medicineId
WHERE pharmacy_medicine.pharmacyId = :pharmacyId
"""
)
suspend fun getPharmacyMedicineByPharmacyId(pharmacyId: Long): List<PharmacyMedicineFlatEntity>

@Query("DELETE FROM medicines")
suspend fun clearAllMedicines()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package pt.ulisboa.ist.pharmacist.repository.local.medicines

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

Expand All @@ -17,8 +18,16 @@ data class MedicineEntity(
val name: String,
val description: String,
val boxPhotoUrl: String,
val closestPharmacy: Long?,
val notificationsActive: Boolean
@ColumnInfo(defaultValue = "0") val notificationsActive: Boolean
)

data class MedicineWithClosestPharmacyEntity(
val medicineId: Long,
val name: String,
val description: String,
val boxPhotoUrl: String,
val closestPharmacyId: Long?,
val closestPharmacyName: String?
)


Expand All @@ -27,7 +36,6 @@ data class PharmacyMedicineFlatEntity(
val name: String,
val description: String,
val boxPhotoUrl: String,
val closestPharmacy: Long?,
val notificationsActive: Boolean,
val stock: Long?
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface PharmacyDao {

@Query(
"""
SELECT pharmacies.pharmacyId, pharmacies.name, pharmacies.location, pharmacies.pictureUrl, pharmacies.globalRating, pharmacies.numberOfRatings,
SELECT pharmacies.pharmacyId, pharmacies.name, pharmacies.latitude, pharmacies.longitude, pharmacies.pictureUrl, pharmacies.globalRating, pharmacies.numberOfRatings,
pharmacies.userRating, pharmacies.userMarkedAsFavorite, pharmacies.userFlagged
FROM pharmacies
JOIN pharmacy_medicine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import pt.ulisboa.ist.pharmacist.domain.pharmacies.Location
data class PharmacyEntity(
@PrimaryKey val pharmacyId: Long,
val name: String,
val location: Location,
val latitude: Double,
val longitude: Double,
val pictureUrl: String,
val globalRating: Double?,
val numberOfRatings: Array<Int>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,16 @@ import pt.ulisboa.ist.pharmacist.domain.medicines.Medicine
import pt.ulisboa.ist.pharmacist.domain.medicines.MedicineWithClosestPharmacy
import pt.ulisboa.ist.pharmacist.domain.medicines.MedicineWithNotificationStatus
import pt.ulisboa.ist.pharmacist.repository.local.medicines.MedicineEntity
import pt.ulisboa.ist.pharmacist.repository.local.medicines.MedicineWithClosestPharmacyEntity
import pt.ulisboa.ist.pharmacist.repository.local.medicines.PharmacyMedicineEntity
import pt.ulisboa.ist.pharmacist.repository.remote.medicines.GetMedicineOutputDto
import pt.ulisboa.ist.pharmacist.repository.remote.medicines.MedicineDto
import pt.ulisboa.ist.pharmacist.repository.remote.pharmacies.MedicineStockDto

fun MedicineDto.toMedicineEntity() = MedicineEntity(
medicineId = medicineId,
name = name,
description = description,
boxPhotoUrl = boxPhotoUrl,
closestPharmacy = null,
notificationsActive = false
)

fun GetMedicineOutputDto.toMedicineEntity() = MedicineEntity(
medicineId = medicine.medicineId,
name = medicine.name,
description = medicine.description,
boxPhotoUrl = medicine.boxPhotoUrl,
closestPharmacy = null,
notificationsActive = notificationsActive
)

Expand All @@ -45,7 +35,17 @@ fun MedicineEntity.toMedicineWithClosestPharmacy() = MedicineWithClosestPharmacy
name = name,
description = description,
boxPhotoUrl = boxPhotoUrl,
closestPharmacy = closestPharmacy
closestPharmacyId = null,
closestPharmacyName = null
)

fun MedicineWithClosestPharmacyEntity.toMedicineWithClosestPharmacy() = MedicineWithClosestPharmacy(
medicineId = medicineId,
name = name,
description = description,
boxPhotoUrl = boxPhotoUrl,
closestPharmacyId = closestPharmacyId,
closestPharmacyName = closestPharmacyName
)

fun MedicineEntity.toMedicineWithNotificationStatus() = MedicineWithNotificationStatus(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package pt.ulisboa.ist.pharmacist.repository.mappers

import pt.ulisboa.ist.pharmacist.domain.pharmacies.Location
import pt.ulisboa.ist.pharmacist.domain.pharmacies.Pharmacy
import pt.ulisboa.ist.pharmacist.repository.local.pharmacies.PharmacyEntity
import pt.ulisboa.ist.pharmacist.repository.remote.pharmacies.PharmacyWithUserDataDto

fun PharmacyWithUserDataDto.toPharmacyEntity() = PharmacyEntity(
pharmacyId = pharmacy.pharmacyId,
name = pharmacy.name,
location = pharmacy.location,
latitude = pharmacy.location.lat,
longitude = pharmacy.location.lon,
pictureUrl = pharmacy.pictureUrl,
globalRating = pharmacy.globalRating,
numberOfRatings = pharmacy.numberOfRatings,
Expand All @@ -19,7 +21,7 @@ fun PharmacyWithUserDataDto.toPharmacyEntity() = PharmacyEntity(
fun PharmacyEntity.toPharmacy() = Pharmacy(
pharmacyId = pharmacyId,
name = name,
location = location,
location = Location(lat = latitude, lon = longitude),
pictureUrl = pictureUrl,
globalRating = globalRating,
numberOfRatings = numberOfRatings,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.room.withTransaction
import okio.IOException
import pt.ulisboa.ist.pharmacist.domain.pharmacies.Location
import pt.ulisboa.ist.pharmacist.repository.local.PharmacistDatabase
import pt.ulisboa.ist.pharmacist.repository.local.medicines.MedicineDao
import pt.ulisboa.ist.pharmacist.repository.local.medicines.MedicineEntity
import pt.ulisboa.ist.pharmacist.repository.network.connection.isSuccess

Expand Down Expand Up @@ -60,14 +61,12 @@ class MedicineRemoteMediator(
if (loadType == LoadType.REFRESH)
pharmacistDb.medicineDao().clearAllMedicines()

pharmacistDb.medicineDao().upsertMedicines(result.data.medicines.map {
MedicineEntity(
pharmacistDb.medicineDao().upsertBaseMedicines(result.data.medicines.map {
MedicineDao.MedicineBaseEntity(
medicineId = it.medicine.medicineId,
name = it.medicine.name,
description = it.medicine.description,
boxPhotoUrl = it.medicine.boxPhotoUrl,
closestPharmacy = it.closestPharmacy?.pharmacyId,
notificationsActive = false // TODO: find another way instead of overwriting
boxPhotoUrl = it.medicine.boxPhotoUrl
)
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package pt.ulisboa.ist.pharmacist.repository.remote.medicines

import android.util.Log
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import okio.IOException
import pt.ulisboa.ist.pharmacist.domain.pharmacies.Location
import pt.ulisboa.ist.pharmacist.repository.local.PharmacistDatabase
import pt.ulisboa.ist.pharmacist.repository.local.medicines.MedicineDao
import pt.ulisboa.ist.pharmacist.repository.local.medicines.MedicineWithClosestPharmacyEntity
import pt.ulisboa.ist.pharmacist.repository.network.connection.isSuccess

@OptIn(ExperimentalPagingApi::class)
class MedicineWithClosestPharmacyRemoteMediator(
private val pharmacistDb: PharmacistDatabase,
private val medicineApi: MedicineApi,
private val query: String,
private val location: Location?
) : RemoteMediator<Int, MedicineWithClosestPharmacyEntity>() {

override suspend fun load(
loadType: LoadType,
state: PagingState<Int, MedicineWithClosestPharmacyEntity>
): MediatorResult {
val offset = when (loadType) {
LoadType.REFRESH -> STARTING_KEY
LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
LoadType.APPEND -> {
state.pages.flatten().size
}
}

val limit = state.config.pageSize

Log.d("MedicineRemoteMediator", "LoadType: $loadType")
Log.d(
"MedicineRemoteMediator",
"Item count: ${state.pages.flatten().map { it.medicineId }}"
)
Log.d("MedicineRemoteMediator", "Offset: $offset, Limit: $limit")

return try {
val result = medicineApi.getMedicinesWithClosestPharmacy(
substring = query,
location = location,
limit = limit.toLong(),
offset = offset.toLong()
)

if (!result.isSuccess()) {
return MediatorResult.Error(Exception("Error loading data"))
}

Log.d("MedicineRemoteMediator", "Result: ${result.data.medicines.size}")

pharmacistDb.withTransaction {
if (loadType == LoadType.REFRESH)
pharmacistDb.medicineDao().clearAllMedicines()

pharmacistDb.medicineDao().upsertBaseMedicines(result.data.medicines.map {
MedicineDao.MedicineBaseEntity(
medicineId = it.medicine.medicineId,
name = it.medicine.name,
description = it.medicine.description,
boxPhotoUrl = it.medicine.boxPhotoUrl
)
})
}

Log.d(
"MedicineRemoteMediator",
"Reached end of pagination: ${result.data.medicines.isEmpty() || result.data.medicines.size < limit}"
)

MediatorResult.Success(
endOfPaginationReached =
result.data.medicines.isEmpty() || result.data.medicines.size < limit
)
} catch (e: IOException) {
MediatorResult.Error(e)
} catch (e: Exception) {
MediatorResult.Error(e)
}
}

companion object {
const val STARTING_KEY = 0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ class AddMedicineToPharmacyActivity : PharmacistActivity() {

setContent {
AddMedicineToPharmacyScreen(
loadingState = viewModel.loadingState,
hasLocationPermission = viewModel.hasLocationPermission,
medicinePagingItems = viewModel.medicinePagingFlow?.collectAsLazyPagingItems(),
onSearch = { viewModel.searchMedicines(it) },
onMedicineClicked = { medicine ->
Expand Down
Loading

0 comments on commit 3b2eb37

Please sign in to comment.