Skip to content

Commit

Permalink
437 stock tracking does not work with additional doses (#439)
Browse files Browse the repository at this point in the history
* Rename .java to .kt

* Use stock tracking for manual dose

* Fix unit test

* Fix unit test

* Fix merge error

* Fix test
  • Loading branch information
Futsch1 authored Jan 19, 2025
1 parent ba8a80e commit f674244
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 177 deletions.
17 changes: 14 additions & 3 deletions app/src/androidTest/java/com/futsch1/medtimer/MedicineStockTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assert
import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed
import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertNotContains
import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn
import com.adevinta.android.barista.interaction.BaristaDialogInteractions
import com.adevinta.android.barista.interaction.BaristaEditTextInteractions.writeTo
import com.adevinta.android.barista.interaction.BaristaListInteractions.clickListItem
import com.adevinta.android.barista.interaction.BaristaListInteractions.clickListItemChild
import com.adevinta.android.barista.rule.flaky.AllowFlaky
import com.futsch1.medtimer.AndroidTestHelper.navigateTo
import org.hamcrest.CoreMatchers.equalTo
import org.junit.Test

class MedicineStockTest : BaseTestHelper() {

@Test
//@AllowFlaky(attempts = 1)
@AllowFlaky(attempts = 1)
fun medicineStockTest() {
val context = InstrumentationRegistry.getInstrumentation().targetContext

Expand Down Expand Up @@ -93,15 +95,24 @@ class MedicineStockTest : BaseTestHelper() {
navigateTo(AndroidTestHelper.MainMenu.MEDICINES)
assertContains(R.id.medicineName, "")

navigateTo(AndroidTestHelper.MainMenu.OVERVIEW)
clickOn(R.id.logManualDose)
clickListItem(null, 1)
writeTo(android.R.id.input, "12")
BaristaDialogInteractions.clickDialogPositiveButton()
clickOn(com.google.android.material.R.id.material_timepicker_ok_button)

navigateTo(AndroidTestHelper.MainMenu.MEDICINES)

clickListItem(R.id.medicineList, 0)
clickOn(R.id.openStockTracking)
clickOn(R.id.refillNow)

assertDisplayed(R.id.amountLeft, "14")
assertDisplayed(R.id.amountLeft, "10.5")
pressBack()
pressBack()

assertContains(R.id.medicineName, "14")
assertContains(R.id.medicineName, "10.5")
assertNotContains(R.id.medicineName, "")
}
}
1 change: 1 addition & 0 deletions app/src/main/java/com/futsch1/medtimer/ActivityCodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class ActivityCodes {
public static final String EXTRA_REPEAT_TIME_SECONDS = "com.futsch1.medTimer.EXTRA_REPEAT_TIME_SECONDS";
public static final String EXTRA_REMAINING_REPEATS = "com.futsch1.medTimer.EXTRA_REMAINING_REPEATS";
public static final String EXTRA_AMOUNT = "com.futsch1.medTimer.AMOUNT";
public static final String EXTRA_MEDICINE_ID = "com.futsch1.medTimer.MEDICINE_ID";

public static final String REMINDER_ACTION = "com.futsch1.medTimer.REMINDER_ACTION";
public static final String DISMISSED_ACTION = "com.futsch1.medTimer.DISMISSED_ACTION";
Expand Down
154 changes: 0 additions & 154 deletions app/src/main/java/com/futsch1/medtimer/overview/ManualDose.java

This file was deleted.

158 changes: 158 additions & 0 deletions app/src/main/java/com/futsch1/medtimer/overview/ManualDose.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package com.futsch1.medtimer.overview

import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.SharedPreferences
import androidx.fragment.app.FragmentActivity
import com.futsch1.medtimer.R
import com.futsch1.medtimer.database.Medicine
import com.futsch1.medtimer.database.MedicineRepository
import com.futsch1.medtimer.database.MedicineWithReminders
import com.futsch1.medtimer.database.ReminderEvent
import com.futsch1.medtimer.helpers.DialogHelper
import com.futsch1.medtimer.helpers.TimeHelper
import com.futsch1.medtimer.helpers.TimeHelper.TimePickerWrapper
import com.futsch1.medtimer.helpers.isReminderActive
import com.futsch1.medtimer.reminders.ReminderProcessor
import java.time.Instant
import java.time.LocalDateTime
import java.util.stream.Collectors

class ManualDose(
private val context: Context,
private val medicineRepository: MedicineRepository,
private val activity: FragmentActivity
) {
@Suppress("kotlin:S6291") // Preferences do not contain sensitive date
private val sharedPreferences: SharedPreferences =
context.getSharedPreferences("medtimer.data", Context.MODE_PRIVATE)

fun logManualDose() {
val medicines = medicineRepository.medicines
val entries = getManualDoseEntries(medicines)
val names =
entries.stream().map { e: ManualDoseEntry -> e.name }.collect(Collectors.toList())
.toTypedArray()

// But run the actual dialog on the UI thread again
activity.runOnUiThread {
AlertDialog.Builder(context)
.setItems(names) { _: DialogInterface?, which: Int -> startLogProcess(entries[which]) }
.setTitle(R.string.tab_medicine)
.show()
}
}

private fun getManualDoseEntries(medicines: List<MedicineWithReminders>): List<ManualDoseEntry> {
val lastCustomDose = lastCustomDose!!
val entries: MutableList<ManualDoseEntry> = ArrayList()
entries.add(ManualDoseEntry(context.getString(R.string.custom)))
if (lastCustomDose.isNotBlank()) {
entries.add(ManualDoseEntry(lastCustomDose))
}
for (medicine in medicines) {
entries.add(ManualDoseEntry(medicine.medicine, null))
addInactiveReminders(medicine, entries)
}
return entries
}

private fun startLogProcess(entry: ManualDoseEntry) {
val reminderEvent = ReminderEvent()
// Manual dose is not assigned to an existing reminder
reminderEvent.reminderId = -1
reminderEvent.status = ReminderEvent.ReminderStatus.TAKEN
reminderEvent.medicineName = entry.name
reminderEvent.color = entry.color
reminderEvent.useColor = entry.useColor
reminderEvent.iconId = entry.iconId
if (reminderEvent.medicineName == context.getString(R.string.custom)) {
DialogHelper(context).title(R.string.log_additional_dose).hint(R.string.medicine_name)
.textSink { name: String? ->
lastCustomDose = name
reminderEvent.medicineName = name
getAmountAndContinue(reminderEvent, -1)
}.show()
} else {
if (entry.amount == null) {
getAmountAndContinue(reminderEvent, entry.medicineId)
} else {
reminderEvent.amount = entry.amount
getTimeAndLog(reminderEvent, entry.medicineId)
}
}
}

private var lastCustomDose: String?
get() = sharedPreferences.getString("lastCustomDose", "")
private set(lastCustomDose) {
sharedPreferences.edit().putString("lastCustomDose", lastCustomDose).apply()
}

private fun getAmountAndContinue(reminderEvent: ReminderEvent, medicineId: Int) {
DialogHelper(context).title(R.string.log_additional_dose).hint(R.string.dosage)
.textSink { amount: String? ->
reminderEvent.amount = amount
getTimeAndLog(reminderEvent, medicineId)
}.show()
}

private fun getTimeAndLog(reminderEvent: ReminderEvent, medicineId: Int) {
val localDateTime = LocalDateTime.now()
val timePicker = TimePickerWrapper(activity)
timePicker.show(localDateTime.hour, localDateTime.minute) { minutes: Int ->
reminderEvent.remindedTimestamp =
TimeHelper.instantFromTodayMinutes(minutes).epochSecond
reminderEvent.processedTimestamp = Instant.now().epochSecond
medicineRepository.insertReminderEvent(reminderEvent)
}
if (medicineId != -1) {
ReminderProcessor.requestStockHandling(context, reminderEvent.amount!!, medicineId)
}
}

private class ManualDoseEntry {
val name: String
val color: Int
val useColor: Boolean
val amount: String?
val iconId: Int
val medicineId: Int

constructor(name: String) {
this.name = name
this.color = 0
this.useColor = false
this.amount = null
this.iconId = 0
this.medicineId = -1
}

constructor(medicine: Medicine, amount: String?) {
if (amount != null) {
this.name = medicine.name + " (" + amount + ")"
} else {
this.name = medicine.name
}
this.color = medicine.color
this.useColor = medicine.useColor
this.amount = amount
this.iconId = medicine.iconId
this.medicineId = medicine.medicineId
}
}

companion object {
private fun addInactiveReminders(
medicine: MedicineWithReminders,
entries: MutableList<ManualDoseEntry>
) {
for (reminder in medicine.reminders) {
if (!isReminderActive(reminder)) {
entries.add(ManualDoseEntry(medicine.medicine, reminder.amount))
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ private fun updateReminderEvent(
reminderEvent?.amount = amount
NotificationAction.processReminderEvent(
activity,
reminderEventId,
ReminderEvent.ReminderStatus.TAKEN,
reminderEvent!!,
repository
Expand Down
Loading

0 comments on commit f674244

Please sign in to comment.