Implemented updating AccountTransaction properties
This commit is contained in:
parent
bbfc591e5b
commit
48bffd0316
|
@ -51,11 +51,11 @@ fun TransactionListItem(bank: BankAccess?, transaction: AccountTransactionViewMo
|
|||
|
||||
DI.uiState.showTransferMoneyDialogData.value = ShowTransferMoneyDialogData(
|
||||
DI.uiState.banks.value.firstNotNullOf { it.accounts.firstOrNull { it.id == transaction.accountId } },
|
||||
transaction.otherPartyName,
|
||||
transaction.otherPartyName, // we don't use userSetOtherPartyName here on purpose
|
||||
transactionEntity?.otherPartyBankId,
|
||||
transactionEntity?.otherPartyAccountId,
|
||||
if (withSameData) transaction.amount else null,
|
||||
if (withSameData) transaction.reference else null
|
||||
if (withSameData) transaction.reference else null // we don't use userSetReference here on purpose
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ fun TransactionListItem(bank: BankAccess?, transaction: AccountTransactionViewMo
|
|||
}
|
||||
|
||||
Text(
|
||||
text = transaction.otherPartyName ?: transaction.postingText ?: "",
|
||||
text = transaction.userSetOtherPartyName ?: transaction.otherPartyName ?: transaction.postingText ?: "",
|
||||
Modifier.fillMaxWidth(),
|
||||
color = Style.ListItemHeaderTextColor,
|
||||
fontWeight = Style.ListItemHeaderWeight,
|
||||
|
@ -95,7 +95,7 @@ fun TransactionListItem(bank: BankAccess?, transaction: AccountTransactionViewMo
|
|||
Spacer(modifier = Modifier.height(6.dp))
|
||||
|
||||
Text(
|
||||
text = transaction.reference ?: "",
|
||||
text = transaction.userSetReference ?: transaction.reference ?: "",
|
||||
Modifier.fillMaxWidth(),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
|
@ -121,7 +121,7 @@ fun TransactionListItem(bank: BankAccess?, transaction: AccountTransactionViewMo
|
|||
offset = showMenuAt ?: DpOffset.Zero,
|
||||
) {
|
||||
DropdownMenuItem({ newMoneyTransferToOtherParty(false) }) {
|
||||
Text("Neue Überweisung an ${transaction.otherPartyName} ...")
|
||||
Text("Neue Überweisung an ${transaction.userSetOtherPartyName ?: transaction.otherPartyName} ...") // really use userSetOtherPartyName here as we don't use it in ShowTransferMoneyDialogData
|
||||
}
|
||||
|
||||
DropdownMenuItem({ newMoneyTransferToOtherParty(true) }) {
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
package net.codinux.banking.ui.screens
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import net.codinux.banking.client.model.isNegative
|
||||
import net.codinux.banking.persistence.entities.AccountTransactionEntity
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.extensions.verticalScroll
|
||||
import net.codinux.banking.ui.forms.LabelledValue
|
||||
import net.codinux.banking.ui.forms.OutlinedTextField
|
||||
import net.codinux.banking.ui.forms.SectionHeader
|
||||
|
||||
private val formatUtil = DI.formatUtil
|
||||
|
@ -35,14 +39,50 @@ fun AccountTransactionDetailsScreen(transaction: AccountTransactionEntity, onClo
|
|||
|| transaction.journalNumber != null || transaction.textKeyAddition != null
|
||||
|
||||
|
||||
FullscreenViewBase("Umsatzdetails", onClosed = onClosed) {
|
||||
var enteredOtherPartyName by remember { mutableStateOf(transaction.userSetOtherPartyName ?: transaction.otherPartyName ?: "") }
|
||||
|
||||
var enteredReference by remember { mutableStateOf(transaction.userSetReference ?: transaction.reference ?: "") }
|
||||
|
||||
var enteredNotes by remember { mutableStateOf(transaction.notes ?: "") }
|
||||
|
||||
val hasDataChanged by remember(enteredOtherPartyName, enteredReference, enteredNotes) {
|
||||
mutableStateOf(
|
||||
(enteredOtherPartyName != transaction.userSetOtherPartyName && (transaction.userSetOtherPartyName?.isNotBlank() == true || enteredOtherPartyName.isNotBlank()))
|
||||
|| (enteredReference != transaction.userSetReference && (transaction.userSetReference?.isNotBlank() == true || enteredReference.isNotBlank()))
|
||||
|| (enteredNotes != transaction.notes && enteredNotes.isNotBlank())
|
||||
)
|
||||
}
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
|
||||
fun saveChanges() {
|
||||
coroutineScope.launch {
|
||||
DI.bankingService.updateAccountTransactionEntity(transaction, enteredOtherPartyName.takeUnless { it.isBlank() }, enteredReference.takeUnless { it.isBlank() }, enteredNotes.takeUnless { it.isBlank() })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FullscreenViewBase(
|
||||
"Umsatzdetails",
|
||||
confirmButtonTitle = "Speichern",
|
||||
confirmButtonEnabled = hasDataChanged,
|
||||
showDismissButton = true,
|
||||
onConfirm = { saveChanges() },
|
||||
onClosed = onClosed
|
||||
) {
|
||||
SelectionContainer {
|
||||
Column(Modifier.fillMaxSize().verticalScroll().padding(8.dp)) {
|
||||
Column(Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(8.dp)) {
|
||||
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
SectionHeader(if (isExpense) "Empfänger*in" else "Zahlende*r", false)
|
||||
|
||||
LabelledValue("Name", transaction.otherPartyName ?: "")
|
||||
OutlinedTextField(
|
||||
label = { Text("Name") },
|
||||
value = enteredOtherPartyName,
|
||||
onValueChange = { enteredOtherPartyName = it },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
LabelledValue("BIC", transaction.otherPartyBankId ?: "")
|
||||
|
||||
|
@ -57,7 +97,12 @@ fun AccountTransactionDetailsScreen(transaction: AccountTransactionEntity, onClo
|
|||
|
||||
LabelledValue("Buchungstext", transaction.postingText ?: "")
|
||||
|
||||
LabelledValue("Verwendungszweck", transaction.reference ?: "")
|
||||
OutlinedTextField(
|
||||
label = { Text("Verwendungszweck") },
|
||||
value = enteredReference,
|
||||
onValueChange = { enteredReference = it },
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 8.dp)
|
||||
)
|
||||
|
||||
LabelledValue("Buchungsdatum", formatUtil.formatDate(transaction.bookingDate))
|
||||
|
||||
|
@ -70,6 +115,16 @@ fun AccountTransactionDetailsScreen(transaction: AccountTransactionEntity, onClo
|
|||
transaction.closingBalance?.let {
|
||||
LabelledValue("Tagesendsaldo", formatUtil.formatAmount(it, accountCurrency))
|
||||
}
|
||||
|
||||
OutlinedTextField(
|
||||
label = { Text("Notizen") },
|
||||
value = enteredNotes,
|
||||
onValueChange = { enteredNotes = it },
|
||||
singleLine = false,
|
||||
minLines = 2,
|
||||
maxLines = 3,
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 8.dp)
|
||||
)
|
||||
}
|
||||
|
||||
if (hasDetailedValues) {
|
||||
|
|
|
@ -46,7 +46,10 @@ class AccountTransactionsFilterService {
|
|||
|
||||
private fun matchesSearchTerm(transaction: AccountTransactionViewModel, searchTerm: String): Boolean =
|
||||
transaction.reference?.contains(searchTerm, true) == true
|
||||
|| transaction.userSetReference?.contains(searchTerm, true) == true
|
||||
|| transaction.otherPartyName?.contains(searchTerm, true) == true
|
||||
|| transaction.userSetOtherPartyName?.contains(searchTerm, true) == true
|
||||
|| transaction.postingText?.contains(searchTerm, true) == true
|
||||
|
||||
|
||||
fun filterHoldings(holdings: List<HoldingEntity>, filter: AccountTransactionsFilter): List<HoldingEntity> {
|
||||
|
|
|
@ -19,6 +19,7 @@ class BankDataImporterAndExporter {
|
|||
transactions.forEach { transaction ->
|
||||
writer.writeRow(
|
||||
// TODO: add bank and bank account
|
||||
// TODO: also regard userSetOtherPartyName and userSetReference?
|
||||
formatAmount(transaction.amount, decimalSeparator), transaction.currency,
|
||||
transaction.valueDate.toString(), transaction.bookingDate.toString(),
|
||||
transaction.reference,
|
||||
|
|
|
@ -303,6 +303,31 @@ class BankingService(
|
|||
}
|
||||
|
||||
|
||||
suspend fun updateAccountTransactionEntity(transaction: AccountTransactionEntity, userSetOtherPartyName: String?, userSetReference: String?, notes: String?) {
|
||||
try {
|
||||
bankingRepository.updateTransaction(transaction, userSetOtherPartyName, userSetReference, notes)
|
||||
|
||||
val transactionViewModel = uiState.transactions.value.firstOrNull { it.id == transaction.id } // should actually never be null
|
||||
|
||||
if (transaction.userSetOtherPartyName != userSetOtherPartyName) {
|
||||
transaction.userSetOtherPartyName = userSetOtherPartyName
|
||||
transactionViewModel?.userSetOtherPartyName = userSetOtherPartyName // also update displayed AccountTransactionViewModel
|
||||
}
|
||||
if (transaction.userSetReference != userSetReference) {
|
||||
transaction.userSetReference = userSetReference
|
||||
transactionViewModel?.userSetReference = userSetReference
|
||||
}
|
||||
if (transaction.notes != notes) {
|
||||
transaction.notes = notes
|
||||
}
|
||||
|
||||
notifyAccountTransactionListUpdated()
|
||||
} catch (e: Throwable) {
|
||||
showAndLogError(ErroneousAction.SaveToDatabase, "Could not update account transaction $transaction", "Kontoumsatz konnten nicht aktualisisert werden", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getCurrentUiBanksList() = uiState.banks.value
|
||||
|
||||
private suspend fun notifyBanksListUpdated() {
|
||||
|
@ -321,6 +346,18 @@ class BankingService(
|
|||
uiState.banks.emit(banks)
|
||||
}
|
||||
|
||||
private suspend fun notifyAccountTransactionListUpdated() {
|
||||
val currentTransactionsList = uiState.transactions.value
|
||||
|
||||
if (currentTransactionsList.isNotEmpty()) {
|
||||
// if we only would call uiState.banks.emit(banks) with the same banks list as currently, nothing would change ->
|
||||
// update does not get triggered -> for a short time display a different banks list and then return to actual banks list
|
||||
uiState.transactions.emit(currentTransactionsList.toMutableList().also { it.add(it.last()) })
|
||||
try { delay(10) } catch (e: Throwable) { }
|
||||
uiState.transactions.emit(currentTransactionsList)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTransactionsInUi(addedTransactions: List<AccountTransactionEntity>): List<AccountTransactionViewModel> {
|
||||
val transactionsViewModel = addedTransactions.map { AccountTransactionViewModel(it) }
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ class RecipientFinder(private val bankFinder: BankFinder) {
|
|||
|
||||
suspend fun updateData(transactions: List<AccountTransaction>) {
|
||||
availableRecipients = transactions.mapNotNull {
|
||||
// TODO: also regard userSetOtherPartyName?
|
||||
if (it.otherPartyName != null && it.otherPartyAccountId != null) {
|
||||
RecipientSuggestion(it.otherPartyName!!, it.otherPartyBankId, it.otherPartyAccountId!!)
|
||||
} else {
|
||||
|
@ -45,6 +46,7 @@ class RecipientFinder(private val bankFinder: BankFinder) {
|
|||
|
||||
transactionsByIban = transactions.filter { it.otherPartyAccountId != null }.groupBy { it.otherPartyAccountId!! }
|
||||
.mapValues { it.value.map {
|
||||
// TODO: also regard userSetReference?
|
||||
PaymentDataSuggestion(it.reference ?: "", Amount(it.amount.toString().replace("-", "")), it.currency, it.valueDate)
|
||||
}.toSet().sortedByDescending { it.valueDate } }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue