Implemented returning booked transactions of last 90 days if retrieved from addAccount()

This commit is contained in:
dankl 2019-10-30 23:26:15 +01:00 committed by dankito
parent f5405f8366
commit ce3a7c564d
9 changed files with 109 additions and 30 deletions

View File

@ -6,6 +6,7 @@ import net.dankito.fints.FinTsClientCallback
import net.dankito.fints.banks.BankFinder import net.dankito.fints.banks.BankFinder
import net.dankito.fints.model.* import net.dankito.fints.model.*
import net.dankito.fints.model.mapper.BankDataMapper import net.dankito.fints.model.mapper.BankDataMapper
import net.dankito.fints.response.client.AddAccountResponse
import net.dankito.fints.response.client.FinTsClientResponse import net.dankito.fints.response.client.FinTsClientResponse
import net.dankito.fints.response.client.GetTransactionsResponse import net.dankito.fints.response.client.GetTransactionsResponse
import net.dankito.utils.IThreadPool import net.dankito.utils.IThreadPool
@ -34,8 +35,8 @@ open class MainWindowPresenter(callback: FinTsClientCallback) {
protected val accountAddedListeners = mutableListOf<(BankData, CustomerData) -> Unit>() protected val accountAddedListeners = mutableListOf<(BankData, CustomerData) -> Unit>()
open fun checkIfAccountExists(bankInfo: BankInfo, customerId: String, pin: String, open fun addAccountAsync(bankInfo: BankInfo, customerId: String, pin: String,
callback: (FinTsClientResponse) -> Unit) { callback: (AddAccountResponse) -> Unit) {
val bank = bankDataMapper.mapFromBankInfo(bankInfo) val bank = bankDataMapper.mapFromBankInfo(bankInfo)
val customer = CustomerData(customerId, pin) val customer = CustomerData(customerId, pin)
@ -44,6 +45,8 @@ open class MainWindowPresenter(callback: FinTsClientCallback) {
if (response.isSuccessful) { if (response.isSuccessful) {
accounts.put(customer, bank) accounts.put(customer, bank)
// TODO: show booked transactions of last 90 days in HomeFragment if available
callAccountAddedListeners(bank, customer) callAccountAddedListeners(bank, customer)
} }

View File

@ -1,5 +1,6 @@
package net.dankito.banking.fints4java.android.ui.dialogs package net.dankito.banking.fints4java.android.ui.dialogs
import android.content.DialogInterface
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.DialogFragment import android.support.v4.app.DialogFragment
import android.support.v7.app.AlertDialog import android.support.v7.app.AlertDialog
@ -15,7 +16,7 @@ import net.dankito.banking.fints4java.android.R
import net.dankito.banking.fints4java.android.ui.MainWindowPresenter import net.dankito.banking.fints4java.android.ui.MainWindowPresenter
import net.dankito.banking.fints4java.android.ui.adapter.BankListAdapter import net.dankito.banking.fints4java.android.ui.adapter.BankListAdapter
import net.dankito.fints.model.BankInfo import net.dankito.fints.model.BankInfo
import net.dankito.fints.response.client.FinTsClientResponse import net.dankito.fints.response.client.AddAccountResponse
import net.dankito.utils.android.extensions.asActivity import net.dankito.utils.android.extensions.asActivity
@ -71,32 +72,57 @@ open class AddAccountDialog : DialogFragment() {
val customerId = edtxtCustomerId.text.toString() val customerId = edtxtCustomerId.text.toString()
val pin = edtxtPin.text.toString() val pin = edtxtPin.text.toString()
btnAddAccount.isEnabled = false
pgrbrAddAccount.visibility = View.VISIBLE
presenter.addAccountAsync(selectedBank, customerId, pin) { response -> presenter.addAccountAsync(selectedBank, customerId, pin) { response ->
context?.asActivity()?.runOnUiThread { context?.asActivity()?.runOnUiThread {
btnAddAccount.isEnabled = true
pgrbrAddAccount.visibility = View.GONE
handleAccountCheckResponseOnUiThread(response) handleAccountCheckResponseOnUiThread(response)
} }
} }
} }
} }
protected open fun handleAccountCheckResponseOnUiThread(response: FinTsClientResponse) { protected open fun handleAccountCheckResponseOnUiThread(response: AddAccountResponse) {
context?.let { context -> context?.let { context ->
if (response.isSuccessful) { if (response.isSuccessful) {
AlertDialog.Builder(context)
.setMessage("Successfully added account")
.setPositiveButton(android.R.string.ok) { dialog, _ -> dialog.dismiss() }
.show()
this.dismiss() this.dismiss()
val messageId = if (response.supportsRetrievingTransactionsOfLast90DaysWithoutTan)
R.string.dialog_add_account_message_successfully_added_account_support_retrieving_transactions_of_last_90_days_without_tan
else R.string.dialog_add_account_message_successfully_added_account
AlertDialog.Builder(context)
.setMessage(messageId)
.setPositiveButton(R.string.yes) { dialog, _ -> retrieveAccountTransactionsAndDismiss(response, dialog) }
.setNeutralButton(R.string.later) { dialog, _ -> dialog.dismiss() }
.setNegativeButton(R.string.do_not_ask_anymore) { dialog, _ -> setDoNotAskAnymoreAndDismiss(dialog) }
.show()
} }
else { else {
AlertDialog.Builder(context) AlertDialog.Builder(context)
.setMessage("Could not add account: ${response.exception ?: response.errorsToShowToUser.joinToString("\n")}") .setMessage(context.getString(R.string.dialog_add_account_message_could_not_add_account, (response.exception ?: response.errorsToShowToUser.joinToString("\n"))))
.setPositiveButton(android.R.string.ok) { dialog, _ -> dialog.dismiss() } .setPositiveButton(android.R.string.ok) { dialog, _ -> dialog.dismiss() }
.show() .show()
} }
} }
} }
protected open fun retrieveAccountTransactionsAndDismiss(response: AddAccountResponse, messageDialog: DialogInterface) {
presenter.getAccountTransactionsAsync(response.bank, response.customer) { } // TODO: show error message if not successful. Here or in HomeFragment
messageDialog.dismiss()
}
protected open fun setDoNotAskAnymoreAndDismiss(messageDialog: DialogInterface) {
// TODO: set flag to never retrieve all account transactions
messageDialog.dismiss()
}
protected val otherEditTextChangedWatcher = object : TextWatcher { protected val otherEditTextChangedWatcher = object : TextWatcher {

View File

@ -18,12 +18,12 @@ import net.dankito.banking.fints4java.android.R
import net.dankito.banking.fints4java.android.ui.MainWindowPresenter import net.dankito.banking.fints4java.android.ui.MainWindowPresenter
import net.dankito.banking.fints4java.android.ui.adapter.AccountTransactionAdapter import net.dankito.banking.fints4java.android.ui.adapter.AccountTransactionAdapter
import net.dankito.banking.fints4java.android.ui.dialogs.BankTransferDialog import net.dankito.banking.fints4java.android.ui.dialogs.BankTransferDialog
import net.dankito.fints.model.BankData
import net.dankito.fints.model.BankTransferData import net.dankito.fints.model.BankTransferData
import net.dankito.fints.model.CustomerData
import net.dankito.fints.response.client.GetTransactionsResponse import net.dankito.fints.response.client.GetTransactionsResponse
import net.dankito.utils.android.extensions.asActivity import net.dankito.utils.android.extensions.asActivity
import java.math.BigDecimal import java.math.BigDecimal
import java.util.*
import kotlin.concurrent.schedule
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
@ -135,16 +135,6 @@ class HomeFragment : Fragment() {
// TODO: this is such a bad code style // TODO: this is such a bad code style
(context as? MainActivity)?.presenter?.let { presenter -> (context as? MainActivity)?.presenter?.let { presenter ->
this.presenter = presenter this.presenter = presenter
presenter.addAccountAddedListener { bank, customer ->
retrieveAccountTransactions(bank, customer)
}
}
}
private fun retrieveAccountTransactions(bank: BankData, customer: CustomerData) {
presenter.getAccountTransactionsAsync(bank, customer) { response ->
handleGetTransactionsResponse(response)
} }
} }

View File

@ -95,12 +95,24 @@
android:enabled="false" android:enabled="false"
/> />
<ProgressBar
android:id="@+id/pgrbrAddAccount"
android:layout_width="@dimen/dialog_add_account_progress_bar_width"
android:layout_height="@dimen/dialog_add_account_progress_bar_height"
android:indeterminate="true"
android:layout_toLeftOf="@+id/btnAddAccount"
android:layout_toStartOf="@+id/btnAddAccount"
android:layout_marginLeft="@dimen/dialog_add_account_progress_bar_margin_left"
android:layout_marginStart="@dimen/dialog_add_account_progress_bar_margin_left"
android:visibility="gone"
/>
<Button <Button
android:id="@+id/btnCancel" android:id="@+id/btnCancel"
android:layout_width="@dimen/dialog_add_account_buttons_width" android:layout_width="@dimen/dialog_add_account_buttons_width"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/btnAddAccount" android:layout_toLeftOf="@+id/pgrbrAddAccount"
android:layout_toStartOf="@+id/btnAddAccount" android:layout_toStartOf="@+id/pgrbrAddAccount"
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:text="@string/cancel" android:text="@string/cancel"
/> />

View File

@ -18,6 +18,9 @@
<dimen name="dialog_add_account_edit_text_height">40dp</dimen> <dimen name="dialog_add_account_edit_text_height">40dp</dimen>
<dimen name="dialog_add_account_field_bottom_margin">12dp</dimen> <dimen name="dialog_add_account_field_bottom_margin">12dp</dimen>
<dimen name="dialog_add_account_buttons_width">120dp</dimen> <dimen name="dialog_add_account_buttons_width">120dp</dimen>
<dimen name="dialog_add_account_progress_bar_height">40dp</dimen>
<dimen name="dialog_add_account_progress_bar_width">40dp</dimen>
<dimen name="dialog_add_account_progress_bar_margin_left">12dp</dimen>
<dimen name="list_item_bank_info_height">60dp</dimen> <dimen name="list_item_bank_info_height">60dp</dimen>
<dimen name="list_item_bank_info_icon_supports_fints_30_height">60dp</dimen> <dimen name="list_item_bank_info_icon_supports_fints_30_height">60dp</dimen>

View File

@ -4,6 +4,11 @@
<string name="select">Select</string> <string name="select">Select</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="later">Later</string>
<string name="do_not_ask_anymore">Don\'t ask anymore</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="navigation_drawer_open">Open navigation drawer</string> <string name="navigation_drawer_open">Open navigation drawer</string>
@ -24,6 +29,18 @@
<string name="dialog_add_account_enter_customer_id">Customer Id:</string> <string name="dialog_add_account_enter_customer_id">Customer Id:</string>
<string name="dialog_add_account_enter_pin">Pin:</string> <string name="dialog_add_account_enter_pin">Pin:</string>
<string name="dialog_add_account_add">Add</string> <string name="dialog_add_account_add">Add</string>
<string name="dialog_add_account_message_could_not_add_account">Could not add account: %s</string>
<string name="dialog_add_account_message_successfully_added_account">
Successfully added account.
\n\nWould you like to fetch all account transactions now? If so entering a TAN is required.
\n\nEven if not, please choose your TAN procedure here:
</string>
<string name="dialog_add_account_message_successfully_added_account_support_retrieving_transactions_of_last_90_days_without_tan">
Successfully added account.
\n\nYour bank supports retrieving account transactions of last 90 days without TAN. These are already displayed in background.
\n\nWould you like to fetch all account transactions now? If so entering a TAN is required.
\n\nEven if not, please choose your TAN procedure here:
</string>
<string name="dialog_bank_transfer_remittee_name">Name:</string> <string name="dialog_bank_transfer_remittee_name">Name:</string>
<string name="dialog_bank_transfer_remittee_iban">IBAN:</string> <string name="dialog_bank_transfer_remittee_iban">IBAN:</string>

View File

@ -10,6 +10,7 @@ import net.dankito.fints.model.*
import net.dankito.fints.response.InstituteSegmentId import net.dankito.fints.response.InstituteSegmentId
import net.dankito.fints.response.Response import net.dankito.fints.response.Response
import net.dankito.fints.response.ResponseParser import net.dankito.fints.response.ResponseParser
import net.dankito.fints.response.client.AddAccountResponse
import net.dankito.fints.response.client.FinTsClientResponse import net.dankito.fints.response.client.FinTsClientResponse
import net.dankito.fints.response.client.GetTransactionsResponse import net.dankito.fints.response.client.GetTransactionsResponse
import net.dankito.fints.response.segments.* import net.dankito.fints.response.segments.*
@ -88,7 +89,7 @@ open class FinTsClient @JvmOverloads constructor(
} }
open fun getBankAndCustomerInfoForNewUser(bank: BankData, customer: CustomerData): FinTsClientResponse { open fun getBankAndCustomerInfoForNewUser(bank: BankData, customer: CustomerData): AddAccountResponse {
val dialogData = DialogData() val dialogData = DialogData()
// just to ensure settings are in its initial state and that bank sends use bank parameter (BPD), // just to ensure settings are in its initial state and that bank sends use bank parameter (BPD),
@ -107,19 +108,19 @@ open class FinTsClient @JvmOverloads constructor(
closeDialog(bank, customer, dialogData) closeDialog(bank, customer, dialogData)
return FinTsClientResponse(initDialogResponse) return AddAccountResponse(initDialogResponse, bank, customer)
} }
open fun addAccountAsync(bank: BankData, customer: CustomerData, open fun addAccountAsync(bank: BankData, customer: CustomerData,
callback: (FinTsClientResponse) -> Unit) { callback: (AddAccountResponse) -> Unit) {
threadPool.runAsync { threadPool.runAsync {
callback(addAccount(bank, customer)) callback(addAccount(bank, customer))
} }
} }
open fun addAccount(bank: BankData, customer: CustomerData): FinTsClientResponse { open fun addAccount(bank: BankData, customer: CustomerData): AddAccountResponse {
val newUserInfoResponse = getBankAndCustomerInfoForNewUser(bank, customer) val newUserInfoResponse = getBankAndCustomerInfoForNewUser(bank, customer)
@ -148,8 +149,11 @@ open class FinTsClient @JvmOverloads constructor(
customer.resetSelectedTanProcedure() customer.resetSelectedTanProcedure()
} }
return if (transactionsOfLast90DaysResponse.isSuccessful) transactionsOfLast90DaysResponse return AddAccountResponse(synchronizeCustomerResponse.toResponse(), bank, customer,
else synchronizeCustomerResponse transactionsOfLast90DaysResponse.isSuccessful,
transactionsOfLast90DaysResponse.bookedTransactions,
transactionsOfLast90DaysResponse.unbookedTransactions,
transactionsOfLast90DaysResponse.balance)
} }
@ -180,7 +184,7 @@ open class FinTsClient @JvmOverloads constructor(
val ninetyDaysAgo = Date(Date().time - NinetyDaysAgoMilliseconds) val ninetyDaysAgo = Date(Date().time - NinetyDaysAgoMilliseconds)
val response = getTransactions( val response = getTransactions(
GetTransactionsParameter(false, ninetyDaysAgo), bank, customer) GetTransactionsParameter(true, ninetyDaysAgo), bank, customer)
customer.triedToRetrieveTransactionsOfLast90DaysWithoutTan = true customer.triedToRetrieveTransactionsOfLast90DaysWithoutTan = true

View File

@ -0,0 +1,19 @@
package net.dankito.fints.response.client
import net.dankito.fints.model.AccountTransaction
import net.dankito.fints.model.BankData
import net.dankito.fints.model.CustomerData
import net.dankito.fints.response.Response
import java.math.BigDecimal
open class AddAccountResponse(
response: Response,
val bank: BankData,
val customer: CustomerData,
val supportsRetrievingTransactionsOfLast90DaysWithoutTan: Boolean = false,
val bookedTransactionsOfLast90Days: List<AccountTransaction> = listOf(),
val unbookedTransactionsOfLast90Days: List<Any> = listOf(),
val balance: BigDecimal? = null
)
: FinTsClientResponse(response)

View File

@ -34,4 +34,9 @@ open class FinTsClientResponse(
response.messageCreationError?.allowedVersions ?: listOf(), response.messageCreationError?.allowedVersions ?: listOf(),
response.messageCreationError?.supportedVersions ?: listOf()) response.messageCreationError?.supportedVersions ?: listOf())
open fun toResponse(): Response {
return Response(this.isSuccessful)
}
} }