From a24c5e2c8924ed1dc87bf62d7559c4e5879071e6 Mon Sep 17 00:00:00 2001 From: Julian Date: Sat, 12 Jul 2025 15:13:18 +0200 Subject: [PATCH] proper handling of currency values --- src/main/scala/fahrtenbuch/Database.scala | 2 +- .../components/EntryComponent.scala | 18 ++++++++---- .../components/NewEntryInput.scala | 5 ++-- src/main/scala/fahrtenbuch/model/Entry.scala | 28 +++++++++++++------ 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/main/scala/fahrtenbuch/Database.scala b/src/main/scala/fahrtenbuch/Database.scala index 494c24e..5fa713a 100644 --- a/src/main/scala/fahrtenbuch/Database.scala +++ b/src/main/scala/fahrtenbuch/Database.scala @@ -19,7 +19,7 @@ import scala.util.Success object DexieDB { - private val schemaVersion = 1.1 + private val schemaVersion = 1.3 private val dexieDB: Dexie = new Dexie.^("fahrtenbuch") dexieDB diff --git a/src/main/scala/fahrtenbuch/components/EntryComponent.scala b/src/main/scala/fahrtenbuch/components/EntryComponent.scala index 7eb8a2b..edc017f 100644 --- a/src/main/scala/fahrtenbuch/components/EntryComponent.scala +++ b/src/main/scala/fahrtenbuch/components/EntryComponent.scala @@ -111,13 +111,21 @@ class EntryComponent( ) else tr( - td(new Date(entry.date.payload).toISOString()), + td(new Date(entry.date.payload).toDateString()), td(entry.driver.payload), - td(entry.startKm.payload), - td(entry.endKm.payload), + td( + entry.startKm.payload + .setScale(0, BigDecimal.RoundingMode.HALF_UP) + .toString() + ), + td( + entry.endKm.payload + .setScale(0, BigDecimal.RoundingMode.HALF_UP) + .toString() + ), td(entry.animal.payload), - td(s"${entry.costWear}€"), - td(s"${entry.costTotal}€"), + td(s"${entry.costWear.setScale(2, BigDecimal.RoundingMode.HALF_UP)}€"), + td(s"${entry.costTotal.setScale(2, BigDecimal.RoundingMode.HALF_UP)}€"), td(if entry.paid.payload then "Ja" else "Nein"), td( button( diff --git a/src/main/scala/fahrtenbuch/components/NewEntryInput.scala b/src/main/scala/fahrtenbuch/components/NewEntryInput.scala index 6d24bb7..924e4ad 100644 --- a/src/main/scala/fahrtenbuch/components/NewEntryInput.scala +++ b/src/main/scala/fahrtenbuch/components/NewEntryInput.scala @@ -77,8 +77,9 @@ class NewEntryInput(showNewEntryField: Var[Boolean]): onClick --> { val id = EntryId.gen() val driver = LastWriterWins.now(newEntryDriver.ref.value) - val startKm = LastWriterWins.now(newEntryStartKm.ref.value.toDouble) - val endKm = LastWriterWins.now(newEntryEndKm.ref.value.toDouble) + val startKm = + LastWriterWins.now(BigDecimal(newEntryStartKm.ref.value)) + val endKm = LastWriterWins.now(BigDecimal(newEntryEndKm.ref.value)) val animal = LastWriterWins.now(newEntryAnimal.ref.value) val paid = LastWriterWins.now(newEntryPaid.ref.checked) entryEditBus.emit( diff --git a/src/main/scala/fahrtenbuch/model/Entry.scala b/src/main/scala/fahrtenbuch/model/Entry.scala index bec562e..6372854 100644 --- a/src/main/scala/fahrtenbuch/model/Entry.scala +++ b/src/main/scala/fahrtenbuch/model/Entry.scala @@ -26,27 +26,37 @@ object EntryId: case class Entry( id: EntryId, - startKm: LastWriterWins[Double], - endKm: LastWriterWins[Double], + startKm: LastWriterWins[BigDecimal], + endKm: LastWriterWins[BigDecimal], animal: LastWriterWins[String], paid: LastWriterWins[Boolean], driver: LastWriterWins[String], - date: LastWriterWins[Double] + date: LastWriterWins[Double], + gasPricePerKm: LastWriterWins[BigDecimal] = LastWriterWins.now(0.13), + wearPricePerKm: LastWriterWins[BigDecimal] = LastWriterWins.now(0.05) ) derives NativeConverter: val distance = endKm.payload - startKm.payload - // 13 cent pro km, 5 cent Abnutzung - def costGas: Double = distance * 0.13 - def costWear: Double = distance * 0.05 - def costTotal: Double = costGas + costWear + // initial 13 cent pro km, 5 cent Abnutzung + def costGas: BigDecimal = distance * gasPricePerKm.payload + def costWear: BigDecimal = distance * wearPricePerKm.payload + def costTotal: BigDecimal = costGas + costWear object Entry: given Lattice[Entry] = Lattice.derived + given NativeConverter[BigDecimal] with { + extension (a: BigDecimal) + override def toNative: js.Any = + a.toString() + override def fromNative(ps: ParseState): BigDecimal = + BigDecimal(ps.json.asInstanceOf[String]) + } + def apply( id: EntryId, - startKm: LastWriterWins[Double], - endKm: LastWriterWins[Double], + startKm: LastWriterWins[BigDecimal], + endKm: LastWriterWins[BigDecimal], animal: LastWriterWins[String], paid: LastWriterWins[Boolean], driver: LastWriterWins[String]