Showing suggestions for payment reference based on previous payments to this account / IBAN

This commit is contained in:
dankito 2024-09-04 21:34:51 +02:00
parent a41a9bd13a
commit 4761876cf2
3 changed files with 41 additions and 7 deletions

View File

@ -9,6 +9,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.Dispatchers
@ -30,6 +31,8 @@ private val uiState = DI.uiState
private val bankingService = DI.bankingService
private val formatUtil = DI.formatUtil
@Composable
fun TransferMoneyDialog(
onDismiss: () -> Unit,
@ -130,6 +133,7 @@ fun TransferMoneyDialog(
dropdownMaxHeight = 350.dp,
minTextLengthForSearch = 0,
onEnteredTextChanged = { recipientName = it },
getItemTitle = { suggestion -> suggestion.name },
onSelectedItemChanged = {
if (it != null) {
recipientName = it.name
@ -179,13 +183,20 @@ fun TransferMoneyDialog(
Spacer(modifier = Modifier.height(verticalSpace))
OutlinedTextField(
value = paymentReference,
onValueChange = { paymentReference = it },
label = { Text("Verwendungszweck") },
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next)
)
AutocompleteTextFieldNew(
"Verwendungszweck",
dropdownMaxHeight = 250.dp,
minTextLengthForSearch = 0,
onEnteredTextChanged = { paymentReference = it },
onSelectedItemChanged = { paymentReference = it?.reference ?: "" },
fetchSuggestions = { recipientFinder.findPaymentDataForIban(recipientAccountIdentifier) }
) { paymentDataSuggestion ->
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text(formatUtil.formatAmount(paymentDataSuggestion.amount, paymentDataSuggestion.currency), Modifier.widthIn(min = 60.dp), textAlign = TextAlign.End)
Text(paymentDataSuggestion.reference, Modifier.padding(start = 6.dp), maxLines = 1, overflow = TextOverflow.Ellipsis)
}
}
Row(Modifier.padding(top = verticalSpace), verticalAlignment = Alignment.CenterVertically) {
Switch(

View File

@ -0,0 +1,11 @@
package net.codinux.banking.ui.model
import kotlinx.datetime.LocalDate
import net.codinux.banking.client.model.Amount
data class PaymentDataSuggestion(
val reference: String,
val amount: Amount,
val currency: String,
val valueDate: LocalDate // only needed for sorting
)

View File

@ -1,12 +1,16 @@
package net.codinux.banking.ui.service
import net.codinux.banking.client.model.AccountTransaction
import net.codinux.banking.client.model.Amount
import net.codinux.banking.ui.model.PaymentDataSuggestion
import net.codinux.banking.ui.model.RecipientSuggestion
class RecipientFinder(private val bankFinder: BankFinder) {
private var availableRecipients: Set<RecipientSuggestion> = emptySet()
private var transactionsByIban: Map<String, List<PaymentDataSuggestion>> = emptyMap()
fun findRecipients(query: String): Collection<RecipientSuggestion> {
if (query.isBlank()) {
@ -38,6 +42,14 @@ class RecipientFinder(private val bankFinder: BankFinder) {
.onEach { // do this after toSet() so that we don't have to call findBankByBicOrIban() for all the duplicates
it.bankInfo = bankFinder.findBankByBicOrIban(it.bankIdentifier, it.accountIdentifier)
}
transactionsByIban = transactions.filter { it.otherPartyAccountId != null }.groupBy { it.otherPartyAccountId!! }
.mapValues { it.value.map {
PaymentDataSuggestion(it.reference, Amount(it.amount.amount.replace("-", "")), it.currency, it.valueDate)
}.toSet().sortedByDescending { it.valueDate } }
}
fun findPaymentDataForIban(iban: String): Collection<PaymentDataSuggestion> =
transactionsByIban[iban] ?: emptySet()
}