From 78edbd6d720ecb33bd6a29c249e95e70d6919ecf Mon Sep 17 00:00:00 2001 From: dankito Date: Fri, 20 Sep 2024 12:07:43 +0200 Subject: [PATCH] Implemented deleting bank access --- .../banking/persistence/BankingRepository.kt | 3 ++ .../persistence/InMemoryBankingRepository.kt | 5 +++ .../persistence/SqliteBankingRepository.kt | 8 ++++ .../banking/persistence/AccountTransaction.sq | 9 +++++ .../net/codinux/banking/persistence/Bank.sq | 16 ++++++++ .../codinux/banking/ui/dialogs/BaseDialog.kt | 8 ++-- .../banking/ui/dialogs/ConfirmDialog.kt | 32 +++++++++++++++ .../codinux/banking/ui/dialogs/ErrorDialog.kt | 3 +- .../banking/ui/screens/BankSettingsScreen.kt | 40 +++++++++++++++---- .../banking/ui/service/BankingService.kt | 13 ++++++ 10 files changed, 126 insertions(+), 11 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ConfirmDialog.kt diff --git a/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/BankingRepository.kt b/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/BankingRepository.kt index eb33f97..aa81757 100644 --- a/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/BankingRepository.kt +++ b/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/BankingRepository.kt @@ -26,6 +26,9 @@ interface BankingRepository { suspend fun persistBank(bank: BankAccess): BankAccessEntity + suspend fun deleteBank(bank: BankAccessEntity) + + suspend fun persistTransactions(bankAccount: BankAccountEntity, transactions: List): List diff --git a/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/InMemoryBankingRepository.kt b/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/InMemoryBankingRepository.kt index 4bc7016..3057ee5 100644 --- a/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/InMemoryBankingRepository.kt +++ b/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/InMemoryBankingRepository.kt @@ -48,6 +48,11 @@ class InMemoryBankingRepository( return entity } + override suspend fun deleteBank(bank: BankAccessEntity) { + this.banks.remove(bank) + } + + override suspend fun persistTransactions(bankAccount: BankAccountEntity, transactions: List): List { throw NotImplementedError("Lazy developer, method is not implemented") } diff --git a/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/SqliteBankingRepository.kt b/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/SqliteBankingRepository.kt index 9eb760b..5369d40 100644 --- a/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/SqliteBankingRepository.kt +++ b/BankingPersistence/src/commonMain/kotlin/net/codinux/banking/persistence/SqliteBankingRepository.kt @@ -125,6 +125,14 @@ open class SqliteBankingRepository : BankingRepository { } } + override suspend fun deleteBank(bank: BankAccessEntity) { + bankQueries.transaction { + accountTransactionQueries.deleteTransactionsByBankId(bankId = bank.id) + + bankQueries.deleteBank(bank.id) + } + } + fun getAllBankAccounts(): List = bankQueries.getAllBankAccounts { id, bankId, identifier, subAccountNumber, iban, productName, accountHolderName, type, currency, accountLimit, isAccountTypeSupportedByApplication, features, balance, serverTransactionsRetentionDays, lastAccountUpdateTime, retrievedTransactionsFrom, userSetDisplayName, displayIndex, hideAccount, includeInAutomaticAccountsUpdate -> BankAccountEntity( diff --git a/BankingPersistence/src/commonMain/sqldelight/net/codinux/banking/persistence/AccountTransaction.sq b/BankingPersistence/src/commonMain/sqldelight/net/codinux/banking/persistence/AccountTransaction.sq index 0f81d96..54f6f9d 100644 --- a/BankingPersistence/src/commonMain/sqldelight/net/codinux/banking/persistence/AccountTransaction.sq +++ b/BankingPersistence/src/commonMain/sqldelight/net/codinux/banking/persistence/AccountTransaction.sq @@ -145,6 +145,15 @@ SELECT AccountTransaction.* FROM AccountTransaction WHERE id = ?; +deleteTransactionsByBankId { + DELETE FROM BankAccount + WHERE bankId = :bankId; + + DELETE FROM Holding + WHERE bankId = :bankId; +} + + CREATE TABLE IF NOT EXISTS Holding ( diff --git a/BankingPersistence/src/commonMain/sqldelight/net/codinux/banking/persistence/Bank.sq b/BankingPersistence/src/commonMain/sqldelight/net/codinux/banking/persistence/Bank.sq index ef273dd..ed5ec98 100644 --- a/BankingPersistence/src/commonMain/sqldelight/net/codinux/banking/persistence/Bank.sq +++ b/BankingPersistence/src/commonMain/sqldelight/net/codinux/banking/persistence/Bank.sq @@ -79,6 +79,22 @@ SELECT BankAccess.* FROM BankAccess; +deleteBank { + DELETE FROM TanMethod + WHERE bankId = :bankId; + + DELETE FROM TanMedium + WHERE bankId = :bankId; + + DELETE FROM BankAccount + WHERE bankId = :bankId; + + DELETE FROM BankAccess + WHERE id = :bankId; + +} + + CREATE TABLE IF NOT EXISTS BankAccount ( id INTEGER PRIMARY KEY AUTOINCREMENT, diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/BaseDialog.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/BaseDialog.kt index b1bdc89..43c1a84 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/BaseDialog.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/BaseDialog.kt @@ -22,8 +22,10 @@ import net.codinux.banking.ui.forms.* @Composable fun BaseDialog( title: String, + centerTitle: Boolean = false, confirmButtonTitle: String = "OK", confirmButtonEnabled: Boolean = true, + dismissButtonTitle: String = "Abbrechen", showProgressIndicatorOnConfirmButton: Boolean = false, useMoreThanPlatformDefaultWidthOnMobile: Boolean = false, onDismiss: () -> Unit, @@ -38,7 +40,7 @@ fun BaseDialog( Column(Modifier.background(Color.White).padding(8.dp)) { Row(Modifier.fillMaxWidth()) { - HeaderText(title, Modifier.padding(top = 8.dp, bottom = 16.dp).weight(1f)) + HeaderText(title, Modifier.fillMaxWidth().padding(top = 8.dp, bottom = 16.dp).weight(1f), textAlign = if (centerTitle) TextAlign.Center else TextAlign.Start) if (DI.platform.isDesktop) { TextButton(onDismiss, colors = ButtonDefaults.buttonColors(contentColor = Colors.Zinc700, backgroundColor = Color.Transparent)) { @@ -49,9 +51,9 @@ fun BaseDialog( content() - Row(Modifier.fillMaxWidth()) { + Row(Modifier.fillMaxWidth().padding(top = 8.dp)) { TextButton(onClick = onDismiss, Modifier.weight(0.5f)) { - Text("Abbrechen", color = Colors.CodinuxSecondaryColor, textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth()) + Text(dismissButtonTitle, color = Colors.CodinuxSecondaryColor, textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth()) } TextButton( diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ConfirmDialog.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ConfirmDialog.kt new file mode 100644 index 0000000..801f4ee --- /dev/null +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ConfirmDialog.kt @@ -0,0 +1,32 @@ +package net.codinux.banking.ui.dialogs + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@Composable +fun ConfirmDialog( + text: String, + title: String? = null, + confirmButtonTitle: String = "Ja", + dismissButtonTitle: String = "Nein", + onDismiss: () -> Unit, + onConfirm: () -> Unit +) { + + BaseDialog( + title = title ?: "", + centerTitle = true, + confirmButtonTitle = confirmButtonTitle, + dismissButtonTitle = dismissButtonTitle, + onDismiss = { onDismiss() }, + onConfirm = { onConfirm(); onDismiss() } + ) { + Text(text, textAlign = TextAlign.Center, lineHeight = 22.sp, modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ErrorDialog.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ErrorDialog.kt index 912c047..b5409de 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ErrorDialog.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ErrorDialog.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.window.DialogProperties import net.codinux.banking.ui.composables.text.HeaderText import net.codinux.banking.ui.config.Colors import net.codinux.banking.ui.extensions.verticalScroll +import net.codinux.banking.ui.model.Config.NewLine @Composable fun ErrorDialog( @@ -22,7 +23,7 @@ fun ErrorDialog( ) { val effectiveText = if (exception == null) text else { - "$text\r\n\r\nFehlermeldung:\r\n${exception.stackTraceToString()}" + "$text${NewLine}${NewLine}Fehlermeldung:${NewLine}${exception.stackTraceToString()}" } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/BankSettingsScreen.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/BankSettingsScreen.kt index ec6bc1e..11afcb6 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/BankSettingsScreen.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/BankSettingsScreen.kt @@ -2,13 +2,20 @@ package net.codinux.banking.ui.screens import androidx.compose.foundation.layout.* import androidx.compose.material.Text +import androidx.compose.material.TextButton import androidx.compose.runtime.* import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import kotlinx.coroutines.launch import net.codinux.banking.persistence.entities.BankAccessEntity +import net.codinux.banking.ui.config.Colors import net.codinux.banking.ui.config.DI +import net.codinux.banking.ui.dialogs.ConfirmDialog import net.codinux.banking.ui.extensions.verticalScroll import net.codinux.banking.ui.forms.* +import net.codinux.banking.ui.model.Config.NewLine @Composable fun BankSettingsScreen(bank: BankAccessEntity, onClosed: () -> Unit) { @@ -19,6 +26,10 @@ fun BankSettingsScreen(bank: BankAccessEntity, onClosed: () -> Unit) { var enteredPassword by remember { mutableStateOf(bank.password ?: "") } + var showDeleteBankAccessConfirmationDialog by remember { mutableStateOf(false) } + + val coroutineScope = rememberCoroutineScope() + val hasDataChanged by remember(enteredBankName) { mutableStateOf( (enteredBankName != bank.bankName && (bank.userSetDisplayName == null || enteredBankName != bank.userSetDisplayName)) @@ -27,6 +38,21 @@ fun BankSettingsScreen(bank: BankAccessEntity, onClosed: () -> Unit) { } + if (showDeleteBankAccessConfirmationDialog) { + ConfirmDialog( + title = "${bank.displayName} wirklich löschen?", + text = "Dadurch werden auch alle zum Konto gehörenden Daten wie seine Kontoumsätze unwiderruflich gelöscht.${NewLine}Die Daten können nicht widerhergestellt werden.", + onDismiss = { showDeleteBankAccessConfirmationDialog = false }, + onConfirm = { + coroutineScope.launch { + DI.bankingService.deleteBank(bank) + } + onClosed() + } + ) + } + + FullscreenViewBase(bank.displayName, onClosed = onClosed) { Column(Modifier.fillMaxSize().verticalScroll().padding(8.dp)) { Column { @@ -98,13 +124,13 @@ fun BankSettingsScreen(bank: BankAccessEntity, onClosed: () -> Unit) { } } -// Spacer(Modifier.weight(1f)) -// -// Column(Modifier.padding(top = 18.dp, bottom = 18.dp)) { -// TextButton(modifier = Modifier.fillMaxWidth().height(50.dp), onClick = { }, enabled = false) { -// Text("Konto löschen", color = Colors.DestructiveColor, textAlign = TextAlign.Center) -// } -// } + Spacer(Modifier.weight(1f)) + + Column(Modifier.padding(top = 24.dp, bottom = 18.dp)) { + TextButton(modifier = Modifier.fillMaxWidth().height(50.dp), onClick = { showDeleteBankAccessConfirmationDialog = true }) { + Text("Konto löschen", fontSize = 15.sp, color = Colors.DestructiveColor, textAlign = TextAlign.Center) + } + } } } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/BankingService.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/BankingService.kt index 4c1d565..90fc667 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/BankingService.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/BankingService.kt @@ -93,6 +93,19 @@ class BankingService( fun getAllBanks() = bankingRepository.getAllBanks() + suspend fun deleteBank(bank: BankAccessEntity) { + try { + bankingRepository.deleteBank(bank) + + uiState.transactions.value = uiState.transactions.value.filterNot { it.bankId == bank.id } + uiState.holdings.value = uiState.holdings.value.filterNot { it.bankId == bank.id } + uiState.banks.value = uiState.banks.value.toMutableList().also { it.remove(bank) } + } catch (e: Throwable) { + log.error(e) { "Could not delete bank ${bank.displayName}" } + } + } + + fun getAllAccountTransactions() = bankingRepository.getAllAccountTransactions() fun getAllTransactionsForBank(bank: BankAccessEntity) = bankingRepository.getAllTransactionsForBank(bank)