Implemented hiding account and disabling automatic account update

This commit is contained in:
dankito 2020-09-28 23:14:36 +02:00
parent 364b818d84
commit 589e1e673a
24 changed files with 163 additions and 59 deletions

View File

@ -66,6 +66,10 @@ open class BankAccount(
override var displayIndex: Int = 0 override var displayIndex: Int = 0
override var hideAccount = false
override var updateAccountAutomatically = true
override var doNotShowStrikingFetchAllTransactionsView = false override var doNotShowStrikingFetchAllTransactionsView = false

View File

@ -34,6 +34,8 @@ open class BankAccountEntity(
override var haveAllTransactionsBeenRetrieved: Boolean = false, override var haveAllTransactionsBeenRetrieved: Boolean = false,
override var isAccountTypeSupportedByApplication: Boolean = true, override var isAccountTypeSupportedByApplication: Boolean = true,
override var displayIndex: Int = 0, override var displayIndex: Int = 0,
override var hideAccount: Boolean = false,
override var updateAccountAutomatically: Boolean = true,
override var doNotShowStrikingFetchAllTransactionsView: Boolean = false override var doNotShowStrikingFetchAllTransactionsView: Boolean = false
) : IBankAccount<AccountTransactionEntity> { ) : IBankAccount<AccountTransactionEntity> {

View File

@ -46,6 +46,11 @@ open class BankAccountSettingsDialog : SettingsDialogBase() {
edtxtBankAccountName.text = account.displayName edtxtBankAccountName.text = account.displayName
swtchHideAccount.setOnCheckedChangeListener { _, hideAccount -> swtchUpdateAccountAutomatically.isEnabled = hideAccount == false }
swtchHideAccount.isChecked = account.hideAccount
swtchUpdateAccountAutomatically.isChecked = account.updateAccountAutomatically
lvlAccountHolderName.value = account.accountHolderName lvlAccountHolderName.value = account.accountHolderName
lvlAccountIdentifier.value = account.identifier lvlAccountIdentifier.value = account.identifier
lvlSubAccountNumber.setValueAndVisibilityIfValueIsSet(account.subAccountNumber) lvlSubAccountNumber.setValueAndVisibilityIfValueIsSet(account.subAccountNumber)
@ -66,10 +71,15 @@ open class BankAccountSettingsDialog : SettingsDialogBase() {
override val hasUnsavedChanges: Boolean override val hasUnsavedChanges: Boolean
get() = didChange(edtxtBankAccountName, account.displayName) get() = didChange(edtxtBankAccountName, account.displayName)
|| swtchHideAccount.isChecked != account.hideAccount
|| swtchUpdateAccountAutomatically.isChecked != account.updateAccountAutomatically
override fun saveChanges() { override fun saveChanges() {
account.userSetDisplayName = edtxtBankAccountName.text account.userSetDisplayName = edtxtBankAccountName.text
account.hideAccount = swtchHideAccount.isChecked
account.updateAccountAutomatically = swtchUpdateAccountAutomatically.isChecked
presenter.accountUpdated(account) presenter.accountUpdated(account)
} }

View File

@ -42,7 +42,7 @@ open class SettingsDialog : SettingsDialogBase() {
protected open fun setupUI(rootView: View) { protected open fun setupUI(rootView: View) {
rootView.apply { rootView.apply {
toolbar.apply { toolbar.apply {
setupToolbar(this, rootView.context.getString(R.string.dialog_settings_title), false) setupToolbar(this, rootView.context.getString(R.string.settings), false)
} }
val items = createBanksAdapterItems() val items = createBanksAdapterItems()

View File

@ -190,7 +190,7 @@ class HomeFragment : Fragment() {
} }
private fun updateAccountsTransactions() { private fun updateAccountsTransactions() {
presenter.updateSelectedAccountsTransactionsAsync { } presenter.updateSelectedAccountsTransactionsAsync()
} }
private fun handleGetTransactionsResponseOffUiThread(response: GetTransactionsResponse) { private fun handleGetTransactionsResponseOffUiThread(response: GetTransactionsResponse) {
@ -320,20 +320,11 @@ class HomeFragment : Fragment() {
private fun fetchTransactions() { private fun fetchTransactions() {
presenter.selectedAccounts.forEach { account -> presenter.fetchTransactionsOfSelectedAccounts()
if (account.haveAllTransactionsBeenRetrieved) {
presenter.updateAccountTransactionsAsync(account)
}
else {
presenter.fetchAllAccountTransactionsAsync(account)
}
}
} }
private fun fetchAllTransactions() { private fun fetchAllTransactions() {
accountsForWhichNotAllTransactionsHaveBeenFetched.forEach { account -> presenter.fetchAllTransactionsOfSelectedAccounts()
presenter.fetchAllAccountTransactionsAsync(account)
}
} }
} }

View File

@ -105,7 +105,7 @@ open class DrawerView(
, ,
PrimaryDrawerItem() PrimaryDrawerItem()
.withName(R.string.drawer_menu_show_settings_dialog_title) .withName(R.string.settings)
.withIcon(R.drawable.ic_baseline_settings_24) .withIcon(R.drawable.ic_baseline_settings_24)
.withIconColor(ContextCompat.getColorStateList(activity, R.color.primaryTextColor_Dark)!!) .withIconColor(ContextCompat.getColorStateList(activity, R.color.primaryTextColor_Dark)!!)
.withSelectable(false) .withSelectable(false)
@ -163,7 +163,7 @@ open class DrawerView(
} }
private fun createBankAccountsDrawerItems(bank: TypedBankData): List<IDrawerItem<*>> { private fun createBankAccountsDrawerItems(bank: TypedBankData): List<IDrawerItem<*>> {
return bank.accountsSorted.map { account -> return bank.visibleAccountsSorted.map { account ->
SecondaryDrawerItem() SecondaryDrawerItem()
.withName(account.displayName) .withName(account.displayName)
.withLevel(AccountLevel) .withLevel(AccountLevel)

View File

@ -53,6 +53,13 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
> >
<net.dankito.banking.ui.android.views.FormSectionTitle
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/form_section_title_margin_bottom_for_subsequent_edit_text"
android:text="@string/settings"
/>
<net.dankito.banking.ui.android.views.FormEditText <net.dankito.banking.ui.android.views.FormEditText
android:id="@+id/edtxtBankAccountName" android:id="@+id/edtxtBankAccountName"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -61,6 +68,20 @@
android:inputType="text" android:inputType="text"
/> />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swtchHideAccount"
style="@style/FormSwitchStyle"
android:checked="false"
android:text="@string/dialog_bank_account_settings_hide_account"
/>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swtchUpdateAccountAutomatically"
style="@style/FormSwitchStyle"
android:checked="false"
android:text="@string/dialog_bank_account_settings_update_automatically"
/>
</LinearLayout> </LinearLayout>
@ -68,6 +89,7 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/form_section_extra_margin_top"
> >
<net.dankito.banking.ui.android.views.FormSectionTitle <net.dankito.banking.ui.android.views.FormSectionTitle

View File

@ -14,6 +14,7 @@
<string name="search">Suchen</string> <string name="search">Suchen</string>
<string name="add_account">Konto hinzufügen</string> <string name="add_account">Konto hinzufügen</string>
<string name="settings">Einstellungen</string>
<string name="online_banking_credentials_section_title">Online-Banking Zugangsdaten</string> <string name="online_banking_credentials_section_title">Online-Banking Zugangsdaten</string>
<string name="online_banking_credentials_login_name">Login Name</string> <string name="online_banking_credentials_login_name">Login Name</string>
@ -34,7 +35,6 @@
<string name="nav_header_version_label">Version\u0020</string> <string name="nav_header_version_label">Version\u0020</string>
<string name="nav_header_desc">Navigationsbereich</string> <string name="nav_header_desc">Navigationsbereich</string>
<string name="drawer_menu_all_bank_accounts_title">Alle Konten</string> <string name="drawer_menu_all_bank_accounts_title">Alle Konten</string>
<string name="drawer_menu_show_settings_dialog_title">Einstellungen</string>
<string name="floating_action_menu_add_account">Konto</string> <string name="floating_action_menu_add_account">Konto</string>
<string name="floating_action_menu_transfer_money">Überweisung</string> <string name="floating_action_menu_transfer_money">Überweisung</string>
@ -105,7 +105,6 @@
<string name="dialog_enter_atc_error_entered_atc_is_not_a_number">ATC muss eine Zahl sein.\n\nDer eingebene ATC Wert \'%s\' kann jedoch nicht in eine Zahl konvertiert werden.</string> <string name="dialog_enter_atc_error_entered_atc_is_not_a_number">ATC muss eine Zahl sein.\n\nDer eingebene ATC Wert \'%s\' kann jedoch nicht in eine Zahl konvertiert werden.</string>
<string name="dialog_settings_title">Einstellungen</string>
<string name="dialog_settings_send_message_log_title">Message Log senden</string> <string name="dialog_settings_send_message_log_title">Message Log senden</string>
@ -115,6 +114,8 @@
<string name="dialog_bank_settings_delete_account">Konto löschen</string> <string name="dialog_bank_settings_delete_account">Konto löschen</string>
<string name="dialog_bank_account_settings_account_name">Name</string> <string name="dialog_bank_account_settings_account_name">Name</string>
<string name="dialog_bank_account_settings_hide_account">Konto ausblenden</string>
<string name="dialog_bank_account_settings_update_automatically">Konto automatisch updaten</string>
<string name="dialog_bank_account_settings_account_data_section_title">Kontodaten</string> <string name="dialog_bank_account_settings_account_data_section_title">Kontodaten</string>
<string name="dialog_bank_account_setting_account_holder_name">Kontoinhaber</string> <string name="dialog_bank_account_setting_account_holder_name">Kontoinhaber</string>
<string name="dialog_bank_account_setting_bank_account_identifier">Kontonummer</string> <string name="dialog_bank_account_setting_bank_account_identifier">Kontonummer</string>

View File

@ -31,6 +31,9 @@
<dimen name="form_labelled_value_value_text_size">15sp</dimen> <dimen name="form_labelled_value_value_text_size">15sp</dimen>
<dimen name="form_labelled_value_value_margin_bottom">4dp</dimen> <dimen name="form_labelled_value_value_margin_bottom">4dp</dimen>
<dimen name="form_on_off_value_height">30dp</dimen>
<dimen name="form_on_off_value_label_text_size">15sp</dimen>
<dimen name="fragment_account_transaction_margin_start_and_end">4dp</dimen> <dimen name="fragment_account_transaction_margin_start_and_end">4dp</dimen>
<dimen name="fragment_account_transaction_transactions_summary_height">24dp</dimen> <dimen name="fragment_account_transaction_transactions_summary_height">24dp</dimen>
<dimen name="fragment_account_transaction_fetch_transactions_button_height">40dp</dimen> <dimen name="fragment_account_transaction_fetch_transactions_button_height">40dp</dimen>

View File

@ -14,6 +14,7 @@
<string name="search">Search</string> <string name="search">Search</string>
<string name="add_account">Add account</string> <string name="add_account">Add account</string>
<string name="settings">Settings</string>
<string name="online_banking_credentials_section_title">Online banking login data</string> <string name="online_banking_credentials_section_title">Online banking login data</string>
<string name="online_banking_credentials_login_name">Login name</string> <string name="online_banking_credentials_login_name">Login name</string>
@ -34,7 +35,6 @@
<string name="nav_header_version_label">Version\u0020</string> <string name="nav_header_version_label">Version\u0020</string>
<string name="nav_header_desc">Navigation header</string> <string name="nav_header_desc">Navigation header</string>
<string name="drawer_menu_all_bank_accounts_title">All accounts</string> <string name="drawer_menu_all_bank_accounts_title">All accounts</string>
<string name="drawer_menu_show_settings_dialog_title">Settings</string>
<string name="floating_action_menu_add_account">Account</string> <string name="floating_action_menu_add_account">Account</string>
<string name="floating_action_menu_transfer_money">Transfer money</string> <string name="floating_action_menu_transfer_money">Transfer money</string>
@ -105,7 +105,6 @@
<string name="dialog_enter_atc_error_entered_atc_is_not_a_number">ATC has to be a number.\n\nBut entered ATC value \'%s\' cannot be converted to a number.</string> <string name="dialog_enter_atc_error_entered_atc_is_not_a_number">ATC has to be a number.\n\nBut entered ATC value \'%s\' cannot be converted to a number.</string>
<string name="dialog_settings_title">Settings</string>
<string name="dialog_settings_send_message_log_title">Send message log</string> <string name="dialog_settings_send_message_log_title">Send message log</string>
@ -115,6 +114,8 @@
<string name="dialog_bank_settings_delete_account">Delete account</string> <string name="dialog_bank_settings_delete_account">Delete account</string>
<string name="dialog_bank_account_settings_account_name">Name</string> <string name="dialog_bank_account_settings_account_name">Name</string>
<string name="dialog_bank_account_settings_hide_account">Hide account</string>
<string name="dialog_bank_account_settings_update_automatically">Update account automatically</string>
<string name="dialog_bank_account_settings_account_data_section_title">Account data</string> <string name="dialog_bank_account_settings_account_data_section_title">Account data</string>
<string name="dialog_bank_account_setting_account_holder_name">Account holder name</string> <string name="dialog_bank_account_setting_account_holder_name">Account holder name</string>
<string name="dialog_bank_account_setting_bank_account_identifier">Account identifier</string> <string name="dialog_bank_account_setting_bank_account_identifier">Account identifier</string>

View File

@ -78,4 +78,16 @@
<item name="android:src">@drawable/fab_add</item> <item name="android:src">@drawable/fab_add</item>
</style> </style>
<style name="FormSwitchStyle" parent="Widget.AppCompat.CompoundButton.Switch">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/form_on_off_value_height</item>
<item name="android:textColor">@color/formLabelledValueLabelTextColor</item>
<item name="android:textSize">@dimen/form_on_off_value_label_text_size</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
<item name="android:gravity">center_vertical</item>
<item name="android:textAlignment">gravity</item>
</style>
</resources> </resources>

View File

@ -140,8 +140,7 @@ open class AccountTransactionsControlView(
} }
protected open fun updateAccountTransactions(processingIndicatorButton: ProcessingIndicatorButton) { protected open fun updateAccountTransactions(processingIndicatorButton: ProcessingIndicatorButton) {
// TODO: or only update transactions of selected accounts? presenter.updateSelectedAccountsTransactionsAsync {
presenter.updateAccountsTransactionsAsync {
runLater { runLater {
processingIndicatorButton.resetIsProcessing() processingIndicatorButton.resetIsProcessing()
} }

View File

@ -273,7 +273,7 @@ open class AddAccountDialog(protected val presenter: BankingPresenter) : Window(
val userSelection = dialogService.showDialog(Alert.AlertType.CONFIRMATION, message, null, currentStage, ButtonType.YES, ButtonType.NO) val userSelection = dialogService.showDialog(Alert.AlertType.CONFIRMATION, message, null, currentStage, ButtonType.YES, ButtonType.NO)
when (userSelection) { when (userSelection) {
ButtonType.YES -> presenter.fetchAllAccountTransactionsAsync(response.bank) { } ButtonType.YES -> presenter.fetchAllAccountTransactionsAsync(response.bank)
else -> { } // nothing to do then, simply close dialog else -> { } // nothing to do then, simply close dialog
} }

View File

@ -50,6 +50,10 @@ open class BankAccount @JvmOverloads constructor(
override var displayIndex: Int = 0 override var displayIndex: Int = 0
override var hideAccount = false
override var updateAccountAutomatically = true
override var doNotShowStrikingFetchAllTransactionsView = false override var doNotShowStrikingFetchAllTransactionsView = false

View File

@ -30,6 +30,25 @@ interface IBankAccount<TTransaction: IAccountTransaction> : OrderedDisplayable {
var haveAllTransactionsBeenRetrieved: Boolean var haveAllTransactionsBeenRetrieved: Boolean
var isAccountTypeSupportedByApplication: Boolean var isAccountTypeSupportedByApplication: Boolean
var userSetDisplayName: String? var userSetDisplayName: String?
/**
* Account will not be visible in UI
*/
var hideAccount: Boolean
/**
* Account is still visible in UI but will not be included in automatic accounts refresh (Kontorundruf) or if multiple accounts get updated.
*
* However it still can be updated if navigated to that single account and call update there.
*/
var updateAccountAutomatically: Boolean
/**
* If there are still older transactions to fetch, that is [haveAllTransactionsBeenRetrieved] is [false], at a striking place,
* e.g. above transactions list or with an overlay, an information will be displayed to fetch all transactions.
*
* However this information can be dismissed by user. Than it still will be visible below transactions list where it's not that well visible to user.
*/
var doNotShowStrikingFetchAllTransactionsView: Boolean var doNotShowStrikingFetchAllTransactionsView: Boolean

View File

@ -43,6 +43,9 @@ interface IBankData<TAccount: IBankAccount<TAccountTransaction>, TAccountTransac
val accountsSorted: List<TAccount> val accountsSorted: List<TAccount>
get() = accounts.sortedByDisplayIndex() get() = accounts.sortedByDisplayIndex()
val visibleAccountsSorted: List<TAccount>
get() = accountsSorted.filter { it.hideAccount == false }
val balance: BigDecimal val balance: BigDecimal
get() = accounts.map { it.balance }.sum() get() = accounts.map { it.balance }.sum()

View File

@ -115,7 +115,7 @@ open class BankingPresenter(
readAppSettings() readAppSettings()
readPersistedBanks() readPersistedBanks()
updateAccountsTransactionsIfNoTanIsRequiredAsync() updateAllAccountsTransactionsAsync()
} }
// preloadBankList asynchronously; on Android it takes approximately 18 seconds till banks are indexed for first time -> do it as early as possible // preloadBankList asynchronously; on Android it takes approximately 18 seconds till banks are indexed for first time -> do it as early as possible
@ -252,7 +252,7 @@ open class BankingPresenter(
} }
protected open fun deleteAccountOffUiThread(bank: TypedBankData) { protected open fun deleteAccountOffUiThread(bank: TypedBankData) {
val wasSelected = isSingleSelectedBank(bank) or // either account or one of its bank accounts is currently selected val wasSelected = isSingleSelectedBank(bank) or // either bank or one of its bank accounts is currently selected
(bank.accounts.firstOrNull { isSingleSelectedAccount(it) } != null) (bank.accounts.firstOrNull { isSingleSelectedAccount(it) } != null)
val client = bankingClientsForBanks.remove(bank) val client = bankingClientsForBanks.remove(bank)
@ -278,6 +278,28 @@ open class BankingPresenter(
} }
/**
* If for an account already all transactions have been fetch, then latest transactions get fetched.
*
* Otherwise all transactions are fetched.
*/
open fun fetchTransactionsOfSelectedAccounts(callback: ((GetTransactionsResponse) -> Unit)? = null) {
selectedAccounts.forEach { account ->
if (account.haveAllTransactionsBeenRetrieved) {
updateAccountTransactionsAsync(account, false, callback)
}
else {
fetchAllAccountTransactionsAsync(account, callback)
}
}
}
open fun fetchAllTransactionsOfSelectedAccounts(callback: ((GetTransactionsResponse) -> Unit)? = null) {
selectedAccountsForWhichNotAllTransactionsHaveBeenFetched.forEach { account ->
fetchAllAccountTransactionsAsync(account, callback)
}
}
open fun fetchAllAccountTransactionsAsync(bank: TypedBankData, open fun fetchAllAccountTransactionsAsync(bank: TypedBankData,
callback: ((GetTransactionsResponse) -> Unit)? = null) { callback: ((GetTransactionsResponse) -> Unit)? = null) {
@ -288,13 +310,13 @@ open class BankingPresenter(
} }
} }
open fun fetchAllAccountTransactionsAsync(account: TypedBankAccount, protected open fun fetchAllAccountTransactionsAsync(account: TypedBankAccount,
callback: ((GetTransactionsResponse) -> Unit)? = null) { callback: ((GetTransactionsResponse) -> Unit)? = null) {
fetchAccountTransactionsAsync(account, null, false, callback) fetchAccountTransactionsAsync(account, null, false, callback)
} }
open fun fetchAccountTransactionsAsync(account: TypedBankAccount, fromDate: Date?, abortIfTanIsRequired: Boolean = false, protected open fun fetchAccountTransactionsAsync(account: TypedBankAccount, fromDate: Date?, abortIfTanIsRequired: Boolean = false,
callback: ((GetTransactionsResponse) -> Unit)? = null) { callback: ((GetTransactionsResponse) -> Unit)? = null) {
getBankingClientForBank(account.bank)?.let { client -> getBankingClientForBank(account.bank)?.let { client ->
@ -311,29 +333,25 @@ open class BankingPresenter(
} }
} }
open fun updateAccountsTransactionsAsync(callback: (GetTransactionsResponse) -> Unit) {
updateAccountsTransactionsAsync(false, callback) open fun updateAllAccountsTransactionsAsync(callback: ((GetTransactionsResponse) -> Unit)? = null) {
val accountsToUpdate = allAccounts.filter { it.hideAccount == false && it.updateAccountAutomatically }
updateAccountsTransactionsAsync(accountsToUpdate, true, callback)
} }
open fun updateAccountsTransactionsIfNoTanIsRequiredAsync() { open fun updateSelectedAccountsTransactionsAsync(callback: ((GetTransactionsResponse) -> Unit)? = null) {
updateAccountsTransactionsAsync(true) { } var accountsToUpdate = selectedAccounts.filter { it.updateAccountAutomatically }
} if (accountsToUpdate.isEmpty() && (selectedAccountType == SelectedAccountType.SingleAccount
|| (selectedAccountType == SelectedAccountType.SingleBank && selectedAccounts.size == 1))) {
open fun updateSelectedAccountsTransactionsAsync(callback: (GetTransactionsResponse) -> Unit) { accountsToUpdate = selectedAccounts
updateAccountsTransactionsAsync(selectedAccounts, false, callback)
}
protected open fun updateAccountsTransactionsAsync(abortIfTanIsRequired: Boolean = false, callback: (GetTransactionsResponse) -> Unit) {
bankingClientsForBanks.keys.forEach { account ->
account.accounts.forEach { account ->
if (account.supportsRetrievingAccountTransactions) {
updateAccountTransactionsAsync(account, abortIfTanIsRequired, callback)
}
}
} }
updateAccountsTransactionsAsync(accountsToUpdate, false, callback)
} }
protected open fun updateAccountsTransactionsAsync(accounts: List<TypedBankAccount>, abortIfTanIsRequired: Boolean = false, callback: (GetTransactionsResponse) -> Unit) {
protected open fun updateAccountsTransactionsAsync(accounts: List<TypedBankAccount>, abortIfTanIsRequired: Boolean = false, callback: ((GetTransactionsResponse) -> Unit)? = null) {
accounts.forEach { account -> accounts.forEach { account ->
if (account.supportsRetrievingAccountTransactions) { if (account.supportsRetrievingAccountTransactions) {
updateAccountTransactionsAsync(account, abortIfTanIsRequired, callback) updateAccountTransactionsAsync(account, abortIfTanIsRequired, callback)
@ -733,7 +751,7 @@ open class BankingPresenter(
} }
protected open fun setSelectedAccounts(accounts: List<TypedBankAccount>) { protected open fun setSelectedAccounts(accounts: List<TypedBankAccount>) {
this._selectedAccounts = ArrayList(accounts) // make a copy this._selectedAccounts = ArrayList(accounts.filter { it.hideAccount == false }) // make a copy
callSelectedAccountsChangedListeners(_selectedAccounts) callSelectedAccountsChangedListeners(_selectedAccounts)
} }

View File

@ -44,6 +44,7 @@
<attribute name="displayIndex" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/> <attribute name="displayIndex" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="doNotShowStrikingFetchAllTransactionsView" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/> <attribute name="doNotShowStrikingFetchAllTransactionsView" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="haveAllTransactionsBeenRetrieved" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/> <attribute name="haveAllTransactionsBeenRetrieved" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="hideAccount" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="iban" optional="YES" attributeType="String"/> <attribute name="iban" optional="YES" attributeType="String"/>
<attribute name="identifier" attributeType="String"/> <attribute name="identifier" attributeType="String"/>
<attribute name="isAccountTypeSupportedByApplication" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/> <attribute name="isAccountTypeSupportedByApplication" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
@ -56,6 +57,7 @@
<attribute name="supportsRetrievingBalance" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/> <attribute name="supportsRetrievingBalance" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="supportsTransferringMoney" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/> <attribute name="supportsTransferringMoney" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="type" attributeType="String"/> <attribute name="type" attributeType="String"/>
<attribute name="updateAccountAutomatically" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="userSetDisplayName" optional="YES" attributeType="String"/> <attribute name="userSetDisplayName" optional="YES" attributeType="String"/>
<relationship name="bank" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PersistedBankData" inverseName="accounts" inverseEntity="PersistedBankData"/> <relationship name="bank" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PersistedBankData" inverseName="accounts" inverseEntity="PersistedBankData"/>
<relationship name="transactions" toMany="YES" deletionRule="Cascade" destinationEntity="PersistedAccountTransaction" inverseName="account" inverseEntity="PersistedAccountTransaction"/> <relationship name="transactions" toMany="YES" deletionRule="Cascade" destinationEntity="PersistedAccountTransaction" inverseName="account" inverseEntity="PersistedAccountTransaction"/>
@ -91,7 +93,7 @@
</entity> </entity>
<elements> <elements>
<element name="PersistedAccountTransaction" positionX="-36" positionY="45" width="128" height="553"/> <element name="PersistedAccountTransaction" positionX="-36" positionY="45" width="128" height="553"/>
<element name="PersistedBankAccount" positionX="-54" positionY="63" width="128" height="28"/> <element name="PersistedBankAccount" positionX="-54" positionY="63" width="128" height="403"/>
<element name="PersistedBankData" positionX="-63" positionY="-18" width="128" height="283"/> <element name="PersistedBankData" positionX="-63" positionY="-18" width="128" height="283"/>
<element name="PersistedTanMedium" positionX="-45" positionY="144" width="128" height="28"/> <element name="PersistedTanMedium" positionX="-45" positionY="144" width="128" height="28"/>
<element name="PersistedTanMethod" positionX="-54" positionY="135" width="128" height="118"/> <element name="PersistedTanMethod" positionX="-54" positionY="135" width="128" height="118"/>

View File

@ -178,6 +178,9 @@ Unfortunately, Bankmeister cannot know whether a bank charges for real-time tran
/* BankAccountSettingsDialog */ /* BankAccountSettingsDialog */
"Account holder name" = "Account holder name"; "Account holder name" = "Account holder name";
"Hide bank account" = "Hide account";
"Update bank account automatically" = "Update account automatically";
"Bank account identifier" = "Account identifier"; "Bank account identifier" = "Account identifier";
"Sub account number" = "Sub account number"; "Sub account number" = "Sub account number";
"Bank account type" = "Type"; "Bank account type" = "Type";

View File

@ -179,6 +179,9 @@ Ob eine Bank Gebühren für Echtzeitüberweisungen erhebt, kann Bankmeister leid
/* BankAccountSettingsDialog */ /* BankAccountSettingsDialog */
"Account holder name" = "Kontoinhaber"; "Account holder name" = "Kontoinhaber";
"Hide bank account" = "Konto ausblenden";
"Update bank account automatically" = "Konto automatisch updaten";
"Bank account identifier" = "Kontonummer"; "Bank account identifier" = "Kontonummer";
"Sub account number" = "Unterkontenmerkmal"; "Sub account number" = "Unterkontenmerkmal";
"Bank account type" = "Typ"; "Bank account type" = "Typ";

View File

@ -218,20 +218,11 @@ struct AccountTransactionsDialog: View {
} }
private func fetchTransactions() { private func fetchTransactions() {
for account in presenter.selectedAccounts { presenter.fetchTransactionsOfSelectedAccounts(callback: self.handleGetTransactionsResult)
if account.haveAllTransactionsBeenRetrieved {
presenter.updateAccountTransactionsAsync(account: account, abortIfTanIsRequired: false, callback: self.handleGetTransactionsResult)
}
else {
presenter.fetchAllAccountTransactionsAsync(account: account, callback: self.handleGetTransactionsResult)
}
}
} }
private func fetchAllTransactions() { private func fetchAllTransactions() {
accountsForWhichNotAllTransactionsHaveBeenFetched.forEach { account in presenter.fetchAllTransactionsOfSelectedAccounts(callback: self.handleGetTransactionsResult)
presenter.fetchAllAccountTransactionsAsync(account: account, callback: self.handleGetTransactionsResult)
}
} }
private func handleGetTransactionsResult(_ response: GetTransactionsResponse) { private func handleGetTransactionsResult(_ response: GetTransactionsResponse) {

View File

@ -37,7 +37,7 @@ struct AccountsDialog: View {
.systemGroupedBackground() .systemGroupedBackground()
.showNavigationBarTitle("Accounts") .showNavigationBarTitle("Accounts")
.navigationBarItems(leading: data.hasAtLeastOneAccountBeenAdded == false ? nil : UpdateButton { _, executingDone in .navigationBarItems(leading: data.hasAtLeastOneAccountBeenAdded == false ? nil : UpdateButton { _, executingDone in
self.presenter.updateAccountsTransactionsAsync { _ in executingDone() } self.presenter.updateAllAccountsTransactionsAsync { _ in executingDone() }
}) })
} }

View File

@ -13,11 +13,17 @@ struct BankAccountSettingsDialog: View {
@State private var displayName: String @State private var displayName: String
@State private var hideAccount: Bool
@State private var updateAccountAutomatically: Bool
@State private var unsavedChangesMessage: Message? = nil @State private var unsavedChangesMessage: Message? = nil
private var hasUnsavedData: Bool { private var hasUnsavedData: Bool {
return account.displayName != displayName return account.displayName != displayName
|| account.hideAccount != hideAccount
|| account.updateAccountAutomatically != updateAccountAutomatically
} }
@ -25,6 +31,8 @@ struct BankAccountSettingsDialog: View {
self.account = account self.account = account
_displayName = State(initialValue: account.displayName) _displayName = State(initialValue: account.displayName)
_hideAccount = State(initialValue: account.hideAccount)
_updateAccountAutomatically = State(initialValue: account.updateAccountAutomatically)
} }
@ -32,6 +40,11 @@ struct BankAccountSettingsDialog: View {
Form { Form {
Section { Section {
LabelledUIKitTextField(label: "Name", text: $displayName, autocapitalizationType: .none) LabelledUIKitTextField(label: "Name", text: $displayName, autocapitalizationType: .none)
Toggle("Hide bank account", isOn: $hideAccount)
Toggle("Update bank account automatically", isOn: $updateAccountAutomatically)
.disabled(hideAccount)
} }
Section { Section {
@ -80,6 +93,9 @@ struct BankAccountSettingsDialog: View {
if hasUnsavedData { if hasUnsavedData {
account.userSetDisplayName = displayName account.userSetDisplayName = displayName
account.hideAccount = hideAccount
account.updateAccountAutomatically = updateAccountAutomatically
presenter.accountUpdated(account: account) presenter.accountUpdated(account: account)
} }

View File

@ -48,7 +48,7 @@ struct BankListItem : View {
// if a constant id like \.technicalId is provided, list doesn't get updated on changes e.g. when balance changes // if a constant id like \.technicalId is provided, list doesn't get updated on changes e.g. when balance changes
ForEach(bank.accountsSorted, id: \.randomId) { account in ForEach(bank.visibleAccountsSorted, id: \.randomId) { account in
BankAccountListItem(account: account) BankAccountListItem(account: account)
} }
.padding(.leading, Styles.AccountsIconWidth + Styles.DefaultSpaceBetweenIconAndText) .padding(.leading, Styles.AccountsIconWidth + Styles.DefaultSpaceBetweenIconAndText)