Implemented fetching all transactions
This commit is contained in:
parent
bab012a9eb
commit
b44161a45f
|
@ -169,7 +169,7 @@ open class AddAccountDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
protected open fun retrieveAccountTransactionsAndDismiss(response: AddAccountResponse, messageDialog: DialogInterface) {
|
||||
presenter.fetchAccountTransactionsAsync(response.customer) { }
|
||||
presenter.fetchAllAccountTransactionsAsync(response.customer) { }
|
||||
|
||||
messageDialog.dismiss()
|
||||
}
|
||||
|
|
|
@ -272,7 +272,7 @@ open class AddAccountDialog(protected val presenter: BankingPresenter) : Window(
|
|||
val userSelection = dialogService.showDialog(Alert.AlertType.CONFIRMATION, message, null, currentStage, ButtonType.YES, ButtonType.NO)
|
||||
|
||||
when (userSelection) {
|
||||
ButtonType.YES -> presenter.fetchAccountTransactionsAsync(response.customer) { }
|
||||
ButtonType.YES -> presenter.fetchAllAccountTransactionsAsync(response.customer) { }
|
||||
else -> { } // nothing to do then, simply close dialog
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,9 @@ open class BankAccount @JvmOverloads constructor(
|
|||
open var technicalId: String = UUID.random()
|
||||
|
||||
|
||||
open var haveAllTransactionsBeenFetched: Boolean = false
|
||||
|
||||
|
||||
open var userSetDisplayName: String? = null
|
||||
|
||||
open val displayName: String
|
||||
|
|
|
@ -167,10 +167,11 @@ open class BankingPresenter(
|
|||
|
||||
if (response.supportsRetrievingTransactionsOfLast90DaysWithoutTan) {
|
||||
response.bookedTransactionsOfLast90Days.keys.forEach { bankAccount ->
|
||||
retrievedAccountTransactions(startDate, GetTransactionsResponse(bankAccount, true, null,
|
||||
retrievedAccountTransactions(GetTransactionsResponse(bankAccount, true, null,
|
||||
response.bookedTransactionsOfLast90Days[bankAccount] ?: listOf(),
|
||||
response.unbookedTransactionsOfLast90Days[bankAccount] ?: listOf(),
|
||||
response.balances[bankAccount])
|
||||
response.balances[bankAccount]),
|
||||
startDate, false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -257,17 +258,17 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
open fun fetchAccountTransactionsAsync(customer: Customer,
|
||||
open fun fetchAllAccountTransactionsAsync(customer: Customer,
|
||||
callback: (GetTransactionsResponse) -> Unit) {
|
||||
|
||||
customer.accounts.forEach { bankAccount ->
|
||||
if (bankAccount.supportsRetrievingAccountTransactions) {
|
||||
fetchAccountTransactionsAsync(bankAccount, callback) // TODO: use a synchronous version of fetchAccountTransactions() so that all bank accounts get handled serially
|
||||
fetchAllAccountTransactionsAsync(bankAccount, callback) // TODO: use a synchronous version of fetchAccountTransactions() so that all bank accounts get handled serially
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open fun fetchAccountTransactionsAsync(bankAccount: BankAccount,
|
||||
open fun fetchAllAccountTransactionsAsync(bankAccount: BankAccount,
|
||||
callback: (GetTransactionsResponse) -> Unit) {
|
||||
|
||||
fetchAccountTransactionsAsync(bankAccount, null, false, callback)
|
||||
|
@ -282,7 +283,7 @@ open class BankingPresenter(
|
|||
client.getTransactionsAsync(bankAccount, GetTransactionsParameter(true, fromDate, null, abortIfTanIsRequired, { receivedAccountsTransactionChunk(bankAccount, it) } )) { response ->
|
||||
|
||||
if (response.tanRequiredButWeWereToldToAbortIfSo == false) { // don't call retrievedAccountTransactions() if aborted due to TAN required but we told client to abort if so
|
||||
retrievedAccountTransactions(startDate, response)
|
||||
retrievedAccountTransactions(response, startDate, fromDate == null)
|
||||
}
|
||||
|
||||
callback(response)
|
||||
|
@ -326,10 +327,14 @@ open class BankingPresenter(
|
|||
fetchAccountTransactionsAsync(bankAccount, fromDate, abortIfTanIsRequired, callback)
|
||||
}
|
||||
|
||||
protected open fun retrievedAccountTransactions(startDate: Date, response: GetTransactionsResponse) {
|
||||
protected open fun retrievedAccountTransactions(response: GetTransactionsResponse, startDate: Date, didFetchAllTransactions: Boolean) {
|
||||
if (response.isSuccessful) {
|
||||
response.bankAccount.lastRetrievedTransactionsTimestamp = startDate
|
||||
|
||||
if (didFetchAllTransactions) {
|
||||
response.bankAccount.haveAllTransactionsBeenFetched = true
|
||||
}
|
||||
|
||||
updateAccountTransactionsAndBalances(response)
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
<attribute name="balance" attributeType="Decimal" defaultValueString="0.0"/>
|
||||
<attribute name="currency" attributeType="String"/>
|
||||
<attribute name="customerId" attributeType="String"/>
|
||||
<attribute name="haveAllTransactionsBeenFetched" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="iban" optional="YES" attributeType="String"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="lastRetrievedTransactionsTimestamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
|
@ -78,7 +79,7 @@
|
|||
</entity>
|
||||
<elements>
|
||||
<element name="PersistedAccountTransaction" positionX="-36" positionY="45" width="128" height="553"/>
|
||||
<element name="PersistedBankAccount" positionX="-54" positionY="63" width="128" height="328"/>
|
||||
<element name="PersistedBankAccount" positionX="-54" positionY="63" width="128" height="343"/>
|
||||
<element name="PersistedCustomer" positionX="-63" positionY="-18" width="128" height="253"/>
|
||||
<element name="PersistedTanProcedure" positionX="-54" positionY="135" width="128" height="88"/>
|
||||
</elements>
|
||||
|
|
|
@ -45,8 +45,15 @@
|
|||
|
||||
/* AccountTransactionsDialog */
|
||||
|
||||
"Fetch all account transactions" = "Alle Umsätze holen";
|
||||
"Transfer money to %@" = "Transfer money to %@";
|
||||
|
||||
"Could not fetch latest transactions" = "Could not fetch latest transactions";
|
||||
"Could not fetch latest transactions for %@. Error message from your bank: %@." = "Could not fetch latest transactions for %@.\nError message from your bank:\n%@.";
|
||||
|
||||
"Could not fetch all transactions" = "Could not fetch all transactions";
|
||||
"Could not fetch all transactions for %@. Error message from your bank: %@." = "Could not fetch all transactions for %@.\nError message from your bank:\n%@.";
|
||||
|
||||
|
||||
/* New action sheet */
|
||||
|
||||
|
|
|
@ -45,8 +45,15 @@
|
|||
|
||||
/* AccountTransactionsDialog */
|
||||
|
||||
"Fetch all account transactions" = "Alle Umsätze holen";
|
||||
"Transfer money to %@" = "Neue Überweisung an %@";
|
||||
|
||||
"Could not fetch latest transactions" = "Umsätze konnte nicht aktualisiert werden";
|
||||
"Could not fetch latest transactions for %@. Error message from your bank: %@." = "Die Umsätze für %@ konnten nicht aktualisiert werden.\nFehlermeldung Ihrer Bank:\n%@.";
|
||||
|
||||
"Could not fetch all transactions" = "Es konnte nicht all Umsätze geholt werden";
|
||||
"Could not fetch all transactions for %@. Error message from your bank: %@." = "Für %@ konnten nicht alle Umsätze geholt werden.\nFehlermeldung Ihrer Bank:\n%@.";
|
||||
|
||||
|
||||
/* New action sheet */
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ class Mapper {
|
|||
func map(_ customer: Customer, _ account: PersistedBankAccount) -> BankAccount {
|
||||
let mapped = BankAccount(customer: customer, identifier: map(account.identifier), accountHolderName: map(account.accountHolderName), iban: account.iban, subAccountNumber: account.subAccountNumber, customerId: map(account.customerId), balance: map(account.balance), currency: map(account.currency), type: map(account.type), productName: account.productName, accountLimit: account.accountLimit, lastRetrievedTransactionsTimestamp: map(account.lastRetrievedTransactionsTimestamp), supportsRetrievingAccountTransactions: account.supportsRetrievingAccountTransactions, supportsRetrievingBalance: account.supportsRetrievingBalance, supportsTransferringMoney: account.supportsTransferringMoney, supportsInstantPaymentMoneyTransfer: account.supportsInstantPaymentMoneyTransfer, bookedTransactions: [], unbookedTransactions: [])
|
||||
|
||||
mapped.haveAllTransactionsBeenFetched = account.haveAllTransactionsBeenFetched
|
||||
|
||||
mapped.userSetDisplayName = account.userSetDisplayName
|
||||
|
||||
mapped.bookedTransactions = map(mapped, account.transactions as? Set<PersistedAccountTransaction>)
|
||||
|
@ -96,6 +98,8 @@ class Mapper {
|
|||
mapped.supportsTransferringMoney = account.supportsTransferringMoney
|
||||
mapped.supportsInstantPaymentMoneyTransfer = account.supportsInstantPaymentMoneyTransfer
|
||||
|
||||
mapped.haveAllTransactionsBeenFetched = account.haveAllTransactionsBeenFetched
|
||||
|
||||
mapped.userSetDisplayName = account.userSetDisplayName
|
||||
|
||||
mapped.transactions = NSSet(array: map(mapped, account.bookedTransactions, context))
|
||||
|
|
|
@ -13,6 +13,13 @@ struct AccountTransactionsDialog: View {
|
|||
private let areMoreThanOneBanksTransactionsDisplayed: Bool
|
||||
|
||||
|
||||
@State private var haveAllTransactionsBeenFetched: Bool
|
||||
|
||||
@State private var showFetchAllTransactionsOverlay: Bool
|
||||
|
||||
@State private var accountsForWhichNotAllTransactionsHaveBeenFetched: [BankAccount]
|
||||
|
||||
|
||||
@State private var filteredTransactions: [AccountTransaction]
|
||||
|
||||
@State private var balanceOfFilteredTransactions: CommonBigDecimal
|
||||
|
@ -29,28 +36,33 @@ struct AccountTransactionsDialog: View {
|
|||
}
|
||||
|
||||
|
||||
@State private var errorMessage: Message? = nil
|
||||
|
||||
|
||||
@Inject private var presenter: BankingPresenterSwift
|
||||
|
||||
|
||||
init(allBanks: [Customer]) {
|
||||
self.init(title: "All accounts", transactions: allBanks.flatMap { $0.accounts }.flatMap { $0.bookedTransactions }, balance: allBanks.sumBalances())
|
||||
let allAccounts = allBanks.flatMap { $0.accounts }
|
||||
|
||||
self.init("All accounts", allAccounts.flatMap { $0.bookedTransactions }, allBanks.sumBalances(), allAccounts.filter { $0.haveAllTransactionsBeenFetched == false })
|
||||
|
||||
presenter.selectedAllBankAccounts()
|
||||
}
|
||||
|
||||
init(bank: Customer) {
|
||||
self.init(title: bank.displayName, transactions: bank.accounts.flatMap { $0.bookedTransactions }, balance: bank.balance)
|
||||
self.init(bank.displayName, bank.accounts.flatMap { $0.bookedTransactions }, bank.balance, bank.accounts.filter { $0.haveAllTransactionsBeenFetched == false })
|
||||
|
||||
presenter.selectedAccount(customer: bank)
|
||||
}
|
||||
|
||||
init(account: BankAccount) {
|
||||
self.init(title: account.displayName, transactions: account.bookedTransactions, balance: account.balance)
|
||||
self.init(account.displayName, account.bookedTransactions, account.balance, account.haveAllTransactionsBeenFetched ? [] : [account])
|
||||
|
||||
presenter.selectedBankAccount(bankAccount: account)
|
||||
}
|
||||
|
||||
fileprivate init(title: String, transactions: [AccountTransaction], balance: CommonBigDecimal) {
|
||||
fileprivate init(_ title: String, _ transactions: [AccountTransaction], _ balance: CommonBigDecimal, _ accountsForWhichNotAllTransactionsHaveBeenFetched: [BankAccount] = []) {
|
||||
self.title = title
|
||||
|
||||
self.allTransactions = transactions
|
||||
|
@ -60,6 +72,10 @@ struct AccountTransactionsDialog: View {
|
|||
self._balanceOfFilteredTransactions = State(initialValue: balance)
|
||||
|
||||
self.areMoreThanOneBanksTransactionsDisplayed = Set(allTransactions.compactMap { $0.bankAccount }.compactMap { $0.customer }).count > 1
|
||||
|
||||
_accountsForWhichNotAllTransactionsHaveBeenFetched = State(initialValue: accountsForWhichNotAllTransactionsHaveBeenFetched)
|
||||
_haveAllTransactionsBeenFetched = State(initialValue: accountsForWhichNotAllTransactionsHaveBeenFetched.isEmpty)
|
||||
_showFetchAllTransactionsOverlay = State(initialValue: accountsForWhichNotAllTransactionsHaveBeenFetched.isNotEmpty)
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,26 +93,86 @@ struct AccountTransactionsDialog: View {
|
|||
}
|
||||
.padding(.horizontal)
|
||||
|
||||
List(filteredTransactions.sorted(by: { $0.valueDate.date > $1.valueDate.date } ), id: \.technicalId) { transaction in
|
||||
Spacer()
|
||||
|
||||
List {
|
||||
ForEach(filteredTransactions.sorted(by: { $0.valueDate.date > $1.valueDate.date } ), id: \.technicalId) { transaction in
|
||||
AccountTransactionListItem(transaction, self.areMoreThanOneBanksTransactionsDisplayed)
|
||||
}
|
||||
|
||||
if haveAllTransactionsBeenFetched == false {
|
||||
Spacer()
|
||||
|
||||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
|
||||
Button("Fetch all account transactions") {
|
||||
self.fetchAllTransactions(self.accountsForWhichNotAllTransactionsHaveBeenFetched)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.frame(height: 35)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
if showFetchAllTransactionsOverlay {
|
||||
HStack(alignment: .center) {
|
||||
Button("x") {
|
||||
self.showFetchAllTransactionsOverlay = false
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Button("Fetch all account transactions") {
|
||||
self.fetchAllTransactions(self.accountsForWhichNotAllTransactionsHaveBeenFetched)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.frame(height: 35)
|
||||
.padding(.top, 8)
|
||||
.padding(.horizontal, 6)
|
||||
.background(Color(UIColor.systemGroupedBackground))
|
||||
}
|
||||
}
|
||||
.alert(item: $errorMessage) { message in
|
||||
Alert(title: message.title, message: message.message, dismissButton: message.primaryButton)
|
||||
}
|
||||
.showNavigationBarTitle(LocalizedStringKey(title))
|
||||
.navigationBarItems(trailing: UpdateButton { _ in self.retrieveTransactions() })
|
||||
.navigationBarItems(trailing: UpdateButton { _ in self.updateTransactions() })
|
||||
}
|
||||
|
||||
|
||||
private func retrieveTransactions() {
|
||||
private func updateTransactions() {
|
||||
presenter.updateSelectedBankAccountTransactionsAsync { response in
|
||||
if response.isSuccessful {
|
||||
self.filterTransactions(self.searchText)
|
||||
}
|
||||
else if response.userCancelledAction == false {
|
||||
// TODO: show updating transactions failed message
|
||||
self.errorMessage = Message(title: Text("Could not fetch latest transactions"), message: Text("Could not fetch latest transactions for \(response.bankAccount.displayName). Error message from your bank: \(response.errorToShowToUser ?? "")."))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchAllTransactions(_ accounts: [BankAccount]) {
|
||||
accounts.forEach { account in
|
||||
presenter.fetchAllAccountTransactionsAsync(bankAccount: account, callback: self.handleGetAllTransactionsResult)
|
||||
}
|
||||
}
|
||||
|
||||
private func handleGetAllTransactionsResult(_ response: GetTransactionsResponse) {
|
||||
self.accountsForWhichNotAllTransactionsHaveBeenFetched = self.accountsForWhichNotAllTransactionsHaveBeenFetched.filter { $0.haveAllTransactionsBeenFetched == false }
|
||||
self.haveAllTransactionsBeenFetched = self.accountsForWhichNotAllTransactionsHaveBeenFetched.isEmpty
|
||||
self.showFetchAllTransactionsOverlay = self.accountsForWhichNotAllTransactionsHaveBeenFetched.isNotEmpty
|
||||
|
||||
if response.isSuccessful == false {
|
||||
self.errorMessage = Message(title: Text("Could not fetch all transactions"), message: Text("Could not fetch all transactions for \(response.bankAccount.displayName). Error message from your bank: \(response.errorToShowToUser ?? "")."))
|
||||
}
|
||||
}
|
||||
|
||||
private func filterTransactions(_ query: String) {
|
||||
self.filteredTransactions = presenter.searchSelectedAccountTransactions(query: query)
|
||||
|
||||
|
@ -107,9 +183,9 @@ struct AccountTransactionsDialog: View {
|
|||
|
||||
struct AccountTransactionsDialog_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountTransactionsDialog(title: previewBanks[0].displayName, transactions: [
|
||||
AccountTransactionsDialog(previewBanks[0].displayName, [
|
||||
AccountTransaction(bankAccount: previewBanks[0].accounts[0], amount: CommonBigDecimal(double: 1234.56), currency: "€", unparsedUsage: "Usage", bookingDate: CommonDate(year: 2020, month: 5, day: 7), otherPartyName: "Marieke Musterfrau", otherPartyBankCode: nil, otherPartyAccountId: nil, bookingText: "SEPA Ueberweisung", valueDate: CommonDate(year: 2020, month: 5, day: 7))
|
||||
],
|
||||
balance: CommonBigDecimal(double: 84.12))
|
||||
CommonBigDecimal(double: 84.12))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue