Skip to content

Commit

Permalink
429 fractional stock for the refill reminder (#438)
Browse files Browse the repository at this point in the history
* Change database fields to double

* Proper formatting and conversion

* Rename .java to .kt

* Finish implementation

* Compile fix

* Update screenshots

* Allow flaky test

* Fix unit test

* Update documentation

* Fix refilling

* Allow flaky test

* Minor refactoring
  • Loading branch information
Futsch1 authored Jan 19, 2025
1 parent cfcae9d commit ba8a80e
Show file tree
Hide file tree
Showing 140 changed files with 221 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"formatVersion": 1,
"database": {
"version": 15,
"identityHash": "91c5f10bab51f886217d048b597b9e53",
"identityHash": "96a7a5b67c4e131b5caa32225e5db9b2",
"entities": [
{
"tableName": "Medicine",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`medicineName` TEXT, `medicineId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `color` INTEGER NOT NULL DEFAULT 0xFFFF0000, `useColor` INTEGER NOT NULL DEFAULT false, `notificationImportance` INTEGER NOT NULL DEFAULT 3, `iconId` INTEGER NOT NULL DEFAULT 0, `outOfStockReminder` TEXT DEFAULT 'OFF', `amount` INTEGER NOT NULL DEFAULT 0, `outOfStockReminderThreshold` INTEGER NOT NULL DEFAULT 0, `refillSizes` TEXT DEFAULT '[]')",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`medicineName` TEXT, `medicineId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `color` INTEGER NOT NULL DEFAULT 0xFFFF0000, `useColor` INTEGER NOT NULL DEFAULT false, `notificationImportance` INTEGER NOT NULL DEFAULT 3, `iconId` INTEGER NOT NULL DEFAULT 0, `outOfStockReminder` TEXT DEFAULT 'OFF', `amount` REAL NOT NULL DEFAULT 0, `outOfStockReminderThreshold` REAL NOT NULL DEFAULT 0, `refillSizes` TEXT DEFAULT '[]')",
"fields": [
{
"fieldPath": "name",
Expand Down Expand Up @@ -58,14 +58,14 @@
{
"fieldPath": "amount",
"columnName": "amount",
"affinity": "INTEGER",
"affinity": "REAL",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "outOfStockReminderThreshold",
"columnName": "outOfStockReminderThreshold",
"affinity": "INTEGER",
"affinity": "REAL",
"notNull": true,
"defaultValue": "0"
},
Expand Down Expand Up @@ -331,7 +331,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '91c5f10bab51f886217d048b597b9e53')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '96a7a5b67c4e131b5caa32225e5db9b2')"
]
}
}
24 changes: 9 additions & 15 deletions app/src/androidTest/java/com/futsch1/medtimer/MedicineStockTest.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.futsch1.medtimer

import androidx.test.espresso.Espresso.onData
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.pressBack
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.matcher.RootMatchers
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
Expand All @@ -21,8 +17,6 @@ import com.adevinta.android.barista.interaction.BaristaListInteractions.clickLis
import com.adevinta.android.barista.interaction.BaristaListInteractions.clickListItemChild
import com.futsch1.medtimer.AndroidTestHelper.navigateTo
import org.hamcrest.CoreMatchers.equalTo
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Test

class MedicineStockTest : BaseTestHelper() {
Expand All @@ -33,17 +27,17 @@ class MedicineStockTest : BaseTestHelper() {
val context = InstrumentationRegistry.getInstrumentation().targetContext

AndroidTestHelper.createMedicine("Test")
// Interval reminder (amount 3) 10 minutes from now
AndroidTestHelper.createIntervalReminder("3", 10)
// Interval reminder (amount 3.5) 10 minutes from now
AndroidTestHelper.createIntervalReminder("Of the pills 3.5 are to be taken", 10)

clickOn(R.id.openStockTracking)
writeTo(R.id.amountLeft, "10")
writeTo(R.id.amountLeft, "10.5")
clickOn(R.id.medicineStockReminder)
onData(equalTo(context.getString(R.string.once_below_threshold))).inRoot(RootMatchers.isPlatformPopup())
.perform(click())
writeTo(R.id.reminderThreshold, "4")
onView(withId(R.id.reminderThreshold)).perform(replaceText("4"), closeSoftKeyboard())
writeTo(R.id.refillSize, "10")
writeTo(R.id.reminderThreshold, "4")
writeTo(R.id.refillSize, "10.5")
pressBack()
pressBack()

Expand All @@ -56,7 +50,7 @@ class MedicineStockTest : BaseTestHelper() {
Until.findObject(By.textContains(context.getString(R.string.out_of_stock_notification_title))),
1_000
)
assertNull(o)
internalAssert(o == null)
device.pressBack()

clickListItemChild(R.id.latestReminders, 0, R.id.chipSkipped)
Expand All @@ -65,7 +59,7 @@ class MedicineStockTest : BaseTestHelper() {
Until.findObject(By.textContains(context.getString(R.string.out_of_stock_notification_title))),
1_000
)
assertNull(o)
internalAssert(o == null)
device.pressBack()

clickListItemChild(R.id.latestReminders, 0, R.id.chipTaken)
Expand All @@ -74,7 +68,7 @@ class MedicineStockTest : BaseTestHelper() {
Until.findObject(By.textContains(context.getString(R.string.out_of_stock_notification_title))),
1_000
)
assertNull(o)
internalAssert(o == null)
device.pressBack()

navigateTo(AndroidTestHelper.MainMenu.MEDICINES)
Expand All @@ -93,7 +87,7 @@ class MedicineStockTest : BaseTestHelper() {
Until.findObject(By.textContains(context.getString(R.string.out_of_stock_notification_title))),
1_000
)
assertNotNull(o)
internalAssert(o != null)
device.pressBack()

navigateTo(AndroidTestHelper.MainMenu.MEDICINES)
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/java/com/futsch1/medtimer/GenerateTestData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ class GenerateTestData(private val viewModel: MedicineViewModel) {
val testReminderOmega3 = TestReminderTimeBased("1", 9 * 60, 1, 0, "")
val testMedicines = arrayOf(
TestMedicine(
"Omega 3 (EPA/DHA 500mg)", null, 1, 10, arrayOf(
"Omega 3 (EPA/DHA 500mg)", null, 1, 10.0, arrayOf(
testReminderOmega3,
TestReminderLinked("1", 9 * 60 + 30, testReminderOmega3)
)
),
TestMedicine(
"B12 (500µg)", -0x750000, 2, 50, arrayOf(
"B12 (500µg)", -0x750000, 2, 50.5, arrayOf(
TestReminderTimeBased("2", 7 * 60, 1, 0, "")
)
),
TestMedicine(
"Ginseng (200mg)", -0x6f1170, 3, 0, arrayOf(
"Ginseng (200mg)", -0x6f1170, 3, 0.0, arrayOf(
TestReminderTimeBased("1", 9 * 60, 1, 0, "before breakfast")
)
),
TestMedicine(
"Selen (200 µg)", null, 0, 0, arrayOf(
"Selen (200 µg)", null, 0, 0.0, arrayOf(
TestReminderTimeBased("2", 9 * 60, 1, 0, ""),
TestReminderIntervalBased("1", 36 * 60)
)
Expand All @@ -48,7 +48,7 @@ class GenerateTestData(private val viewModel: MedicineViewModel) {
val name: String,
val color: Int?,
val iconId: Int,
val stock: Int,
val stock: Double,
val reminders: Array<TestReminder>
) {
override fun equals(other: Any?): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ public static String fromSet(List<Boolean> list) {
}

@TypeConverter
public static ArrayList<Integer> intListFromString(String value) {
Type listType = new TypeToken<ArrayList<Integer>>() {
public static ArrayList<Double> doubleListFromString(String value) {
Type listType = new TypeToken<ArrayList<Double>>() {
}.getType();
return new Gson().fromJson(value, listType);
}

@TypeConverter
public static String fromIntList(ArrayList<Integer> list) {
public static String fromDoubleList(ArrayList<Double> list) {
Gson gson = new Gson();
return gson.toJson(list);
}
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/com/futsch1/medtimer/database/Medicine.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ public class Medicine {
public OutOfStockReminderType outOfStockReminder;
@ColumnInfo(defaultValue = "0")
@Expose
public int amount;
public double amount;
@ColumnInfo(defaultValue = "0")
@Expose
public int outOfStockReminderThreshold;
public double outOfStockReminderThreshold;
@ColumnInfo(defaultValue = "[]")
@Expose
public ArrayList<Integer> refillSizes;
public ArrayList<Double> refillSizes;

public Medicine(String name) {
this.name = name;
Expand Down
30 changes: 0 additions & 30 deletions app/src/main/java/com/futsch1/medtimer/helpers/MedicineHelper.java

This file was deleted.

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

import android.annotation.SuppressLint
import android.content.Context
import com.futsch1.medtimer.R
import com.futsch1.medtimer.database.Medicine
import java.text.NumberFormat
import java.util.regex.Pattern

object MedicineHelper {
private val CYCLIC_COUNT: Pattern = Pattern.compile(" (\\(\\d?/\\d?)\\)")

@JvmStatic
fun normalizeMedicineName(medicineName: String): String {
return CYCLIC_COUNT.matcher(medicineName).replaceAll("")
}

@JvmStatic
@SuppressLint("DefaultLocale")
fun getMedicineNameWithStockText(context: Context, medicine: Medicine): String {
return if (medicine.isStockManagementActive) {
medicine.name + " (" + context.getString(
R.string.medicine_stock_string,
formatAmount(medicine.amount),
if (medicine.amount <= medicine.outOfStockReminderThreshold) " ⚠)" else ")"
)
} else {
medicine.name
}
}

@JvmStatic
fun formatAmount(amount: Double): String {
val numberFormat = NumberFormat.getNumberInstance()
numberFormat.minimumFractionDigits = 0
numberFormat.maximumFractionDigits = 2
return numberFormat.format(amount)
}

fun parseAmount(amount: String): Double? {
val numberRegex = Pattern.compile("\\d+(?:[.,]\\d+)?")
val matcher = numberRegex.matcher(amount)

return if (matcher.find() && matcher.group(0) != null) {
matcher.group(0)?.replace(',', '.')?.toDoubleOrNull()
} else {
null
}
}
}
Loading

0 comments on commit ba8a80e

Please sign in to comment.