Formula Input & rounding & more
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user