Formula Input & rounding & more

This commit is contained in:
2026-09-02 00:43:39 +02:00
parent 42f67dfbe4
commit 72ba99f4b6
3 changed files with 34 additions and 26 deletions
@@ -329,20 +329,18 @@ class EditBillActivity : AppCompatActivity() {
if (splitMode != SplitMode.EVEN) {
val splits: Map<Long, Double> = if (splitMode == SplitMode.CUSTOM) {
viewModel.owersCustomSplit.filter { (id, amountStr) ->
viewModel.owersSelection[id] == true && (amountStr.replace(',', '.').toDoubleOrNull()
?: 0.0) > 0
viewModel.owersSelection[id] == true && viewModel.parseAmountFromUi(amountStr) > 0
}.mapValues {
val uiAmount = it.value.replace(',', '.').toDoubleOrNull() ?: 0.0
val uiAmount = viewModel.parseAmountFromUi(it.value)
SupportUtil.round2(uiAmount / viewModel.selectedCurrencyRate)
}
} else { // PERCENT
val totalAmount = viewModel.amountAsDouble
viewModel.owersPercentSplit.filter { (id, percentStr) ->
viewModel.owersSelection[id] == true && (percentStr.replace(',', '.').toDoubleOrNull()
?: 0.0) > 0
viewModel.owersSelection[id] == true && viewModel.parseAmountFromUi(percentStr) > 0
}.mapValues {
val percent = it.value.replace(',', '.').toDoubleOrNull() ?: 0.0
val uiAmount = totalAmount * percent / 100.0
val percent = viewModel.parseAmountFromUi(it.value)
val uiAmount = SupportUtil.round2(totalAmount * percent / 100.0)
SupportUtil.round2(uiAmount / viewModel.selectedCurrencyRate)
}
}
@@ -193,8 +193,9 @@ fun BillBasicInfoSection(
OutlinedTextField(
value = viewModel.amount,
onValueChange = {
viewModel.amount = it
onValueChange = { nv->
val filteredValue = nv.filter { it in "0123456789.+-*/" }
viewModel.amount = filteredValue
viewModel.updateSplits()
},
enabled = canEdit,
@@ -233,7 +234,7 @@ fun BillBasicInfoSection(
Icon(Icons.Default.SwapHoriz, contentDescription = "Change Currency")
}
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
Spacer(modifier = Modifier.height(8.dp))
@@ -442,13 +443,14 @@ fun OwerSelectionSection(
BasicTextField(
value = value,
onValueChange = {
onValueChange = { nv ->
val filteredValue = nv.filter { it in "0123456789.+-*/" }
if (viewModel.splitMode == SplitMode.PERCENT) {
viewModel.owersPercentSplit[member.id] = it
viewModel.owersPercentSplit[member.id] = filteredValue
} else {
viewModel.owersCustomSplit[member.id] = it
viewModel.owersCustomSplit[member.id] = filteredValue
}
viewModel.owersSelection[member.id] = (it != "")
viewModel.owersSelection[member.id] = (filteredValue != "")
},
modifier = Modifier
.width(80.dp)
@@ -44,18 +44,26 @@ class EditBillViewModel : ViewModel() {
var dialogState by mutableStateOf<DialogState?>(null)
fun parseAmountFromUi(input: String): Double {
if (input.isBlank()) return 0.0
val sanitized = input.replace(',', '.')
// If it contains any math operator, try evalMath first
if (sanitized.any { it in "+-*/" }) {
try {
val result = evalMath(sanitized)
if (result != 0.0) return SupportUtil.round2(result)
} catch (_: Exception) {}
}
val parsed = parseAmount(input) ?: 0.0
return SupportUtil.round2(parsed)
}
val amountAsDouble: Double
get() {
return parseAmount(amount) ?: try {
evalMath(amount.replace(',', '.'))
} catch (_: Exception) {
0.0
}
}
get() = parseAmountFromUi(amount)
fun getEvenSplit(): Double {
val selectedOwersCount = owersSelection.count { it.value }
return if (selectedOwersCount > 0) amountAsDouble / selectedOwersCount else 0.0
return if (selectedOwersCount > 0) SupportUtil.round2(amountAsDouble / selectedOwersCount) else 0.0
}
fun updateSplits() {
@@ -109,13 +117,13 @@ class EditBillViewModel : ViewModel() {
return if (splitMode == SplitMode.PERCENT) {
val customTotal = owersPercentSplit.entries
.filter { owersSelection[it.key] == true }
.sumOf { it.value.replace(',', '.').toDoubleOrNull() ?: 0.0 }
100.0 - customTotal
.sumOf { parseAmountFromUi(it.value) }
SupportUtil.round2(100.0 - customTotal)
} else {
val customTotal = owersCustomSplit.entries
.filter { owersSelection[it.key] == true }
.sumOf { it.value.replace(',', '.').toDoubleOrNull() ?: 0.0 }
amountAsDouble - customTotal
.sumOf { parseAmountFromUi(it.value) }
SupportUtil.round2(amountAsDouble - customTotal)
}
}