diff --git a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj index 40fa6307..e0527604 100644 --- a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj +++ b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj @@ -45,6 +45,8 @@ 36BE065D24CB08FC00CBBB68 /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE065C24CB08FB00CBBB68 /* LazyView.swift */; }; 36BE066524CDE62800CBBB68 /* AccountTransactionListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE066424CDE62800CBBB68 /* AccountTransactionListItem.swift */; }; 36BE068924CE288800CBBB68 /* CollapsibleText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE068824CE288800CBBB68 /* CollapsibleText.swift */; }; + 36BE068B24CE3B0400CBBB68 /* SwiftExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE068A24CE3B0400CBBB68 /* SwiftExtensions.swift */; }; + 36BE068D24CE41E700CBBB68 /* Styles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE068C24CE41E700CBBB68 /* Styles.swift */; }; 36E7BA1424B3D05C00757859 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E7BA1324B3D05C00757859 /* ViewExtensions.swift */; }; 36FC929C24B39A05002B12E9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FC929B24B39A05002B12E9 /* AppDelegate.swift */; }; 36FC929E24B39A05002B12E9 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FC929D24B39A05002B12E9 /* SceneDelegate.swift */; }; @@ -133,6 +135,8 @@ 36BE065C24CB08FB00CBBB68 /* LazyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = ""; }; 36BE066424CDE62800CBBB68 /* AccountTransactionListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTransactionListItem.swift; sourceTree = ""; }; 36BE068824CE288800CBBB68 /* CollapsibleText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleText.swift; sourceTree = ""; }; + 36BE068A24CE3B0400CBBB68 /* SwiftExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftExtensions.swift; sourceTree = ""; }; + 36BE068C24CE41E700CBBB68 /* Styles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Styles.swift; sourceTree = ""; }; 36E7BA1324B3D05C00757859 /* ViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewExtensions.swift; sourceTree = ""; }; 36E7BA1824B9E70C00757859 /* xcode-frameworks */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "xcode-frameworks"; path = "../../tools/BankFinder/build/xcode-frameworks"; sourceTree = ""; }; 36FC929824B39A05002B12E9 /* BankingiOSApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BankingiOSApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -304,6 +308,8 @@ 36BCF88E24C1DFF7005BEC29 /* SheetPresenter.swift */, 366FA4D724C46B160094F009 /* AutoCompleteList.swift */, 36BE068824CE288800CBBB68 /* CollapsibleText.swift */, + 36BE068A24CE3B0400CBBB68 /* SwiftExtensions.swift */, + 36BE068C24CE41E700CBBB68 /* Styles.swift */, ); path = ui; sourceTree = ""; @@ -488,6 +494,7 @@ files = ( 36BE065924CA3CAB00CBBB68 /* UIKitSearchBar.swift in Sources */, 36BE064F24C9A17F00CBBB68 /* ImageTanView.swift in Sources */, + 36BE068D24CE41E700CBBB68 /* Styles.swift in Sources */, 366FA4E224C4ED6C0094F009 /* EnterTanDialog.swift in Sources */, 36FC92DC24B3A4A0002B12E9 /* AccountsTab.swift in Sources */, 36BCF86E24BA691B005BEC29 /* DependencyInjector.swift in Sources */, @@ -503,6 +510,7 @@ 36E7BA1424B3D05C00757859 /* ViewExtensions.swift in Sources */, 36BCF88924C0A7D7005BEC29 /* Message.swift in Sources */, 366FA4E024C4924A0094F009 /* RemitteeListItem.swift in Sources */, + 36BE068B24CE3B0400CBBB68 /* SwiftExtensions.swift in Sources */, 36BE065D24CB08FC00CBBB68 /* LazyView.swift in Sources */, 36BCF86C24BA5E72005BEC29 /* DispatchQueueAsyncRunner.swift in Sources */, 36BCF86324BA5097005BEC29 /* SwiftUiRouter.swift in Sources */, diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/Extensions.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/Extensions.swift index eb504365..4dabde71 100644 --- a/ui/BankingiOSApp/BankingiOSApp/persistence/Extensions.swift +++ b/ui/BankingiOSApp/BankingiOSApp/persistence/Extensions.swift @@ -21,6 +21,14 @@ extension AccountTransaction : Identifiable { } +extension Array where Element == AccountTransaction { + + func sumAmounts() -> CommonBigDecimal { + return CommonBigDecimal(decimal_: self.map { $0.amount.decimal }.sum()) + } + +} + extension BankInfo : Identifiable { diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/Styles.swift b/ui/BankingiOSApp/BankingiOSApp/ui/Styles.swift new file mode 100644 index 00000000..cd881c3d --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/ui/Styles.swift @@ -0,0 +1,11 @@ +import SwiftUI + + +class Styles { + + static let PositiveAmountColor = Color.green + + static let NegativeAmountColor = Color.red + + +} diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/SwiftExtensions.swift b/ui/BankingiOSApp/BankingiOSApp/ui/SwiftExtensions.swift new file mode 100644 index 00000000..2c3971d4 --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/ui/SwiftExtensions.swift @@ -0,0 +1,56 @@ +import SwiftUI + + +extension NSDecimalNumber { + + func isPositive() -> Bool { + return !isNegative() + } + + func isNegative() -> Bool { + return doubleValue < 0.0 + } + + + static func ==(lhs: NSDecimalNumber, rhs: NSDecimalNumber) -> Bool { + return lhs.compare(rhs) == .orderedSame + } + + static func <(lhs: NSDecimalNumber, rhs: NSDecimalNumber) -> Bool { + return lhs.compare(rhs) == .orderedAscending + } + + static prefix func -(value: NSDecimalNumber) -> NSDecimalNumber { + return value.multiplying(by: NSDecimalNumber(mantissa: 1, exponent: 0, isNegative: true)) + } + + static func +(lhs: NSDecimalNumber, rhs: NSDecimalNumber) -> NSDecimalNumber { + return lhs.adding(rhs) + } + + static func -(lhs: NSDecimalNumber, rhs: NSDecimalNumber) -> NSDecimalNumber { + return lhs.subtracting(rhs) + } + + static func *(lhs: NSDecimalNumber, rhs: NSDecimalNumber) -> NSDecimalNumber { + return lhs.multiplying(by: rhs) + } + + static func /(lhs: NSDecimalNumber, rhs: NSDecimalNumber) -> NSDecimalNumber { + return lhs.dividing(by: rhs) + } + + static func ^(lhs: NSDecimalNumber, rhs: Int) -> NSDecimalNumber { + return lhs.raising(toPower: rhs) + } + +} + + +extension Array where Element == NSDecimalNumber { + + func sum() -> NSDecimalNumber { + return self.reduce(NSDecimalNumber.zero, +) + } + +} diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/ViewExtensions.swift b/ui/BankingiOSApp/BankingiOSApp/ui/ViewExtensions.swift index e5d56cab..e7567c41 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/ViewExtensions.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/ViewExtensions.swift @@ -1,4 +1,5 @@ import SwiftUI +import BankingUiSwift extension View { @@ -48,10 +49,18 @@ extension View { .detailForegroundColor() } + func styleAmount(amount: CommonBigDecimal) -> some View { + let amountColor = amount.decimal.isPositive() ? Styles.PositiveAmountColor : Styles.NegativeAmountColor + + return self + .detailFont() + .foregroundColor(amountColor) + } + } -public extension Color { +extension Color { static let lightText = Color(UIColor.lightText) static let darkText = Color(UIColor.darkText) diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/AccountTransactionListItem.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/AccountTransactionListItem.swift index c9012263..860b9949 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/AccountTransactionListItem.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/AccountTransactionListItem.swift @@ -15,16 +15,12 @@ struct AccountTransactionListItem: View { private let transaction: AccountTransaction - private let amountColor: Color - @Inject private var presenter: BankingPresenterSwift init(_ transaction: AccountTransaction) { self.transaction = transaction - - self.amountColor = transaction.amount.decimal.doubleValue < 0.0 ? Color.red : Color.green } @@ -45,8 +41,7 @@ struct AccountTransactionListItem: View { VStack(alignment: .trailing) { Text(presenter.formatAmount(amount: transaction.amount)) - .detailFont() - .foregroundColor(amountColor) + .styleAmount(amount: transaction.amount) Spacer() diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/AccountTransactionsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/AccountTransactionsDialog.swift index 6e623c92..be97332b 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/AccountTransactionsDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/AccountTransactionsDialog.swift @@ -4,13 +4,17 @@ import BankingUiSwift struct AccountTransactionsDialog: View { - private var title: String + private let title: String - private var allTransactions: [AccountTransaction] + private let allTransactions: [AccountTransaction] + + private let balanceOfAllTransactions: CommonBigDecimal @State private var filteredTransactions: [AccountTransaction] + @State private var balanceOfFilteredTransactions: CommonBigDecimal + @State private var searchText = "" private var searchTextBinding: Binding { @@ -26,24 +30,34 @@ struct AccountTransactionsDialog: View { @Inject private var presenter: BankingPresenterSwift - init(title: String, transactions: [AccountTransaction]) { + init(title: String, transactions: [AccountTransaction], balance: CommonBigDecimal) { self.title = title self.allTransactions = transactions self._filteredTransactions = State(initialValue: transactions) + + self.balanceOfAllTransactions = balance + self._balanceOfFilteredTransactions = State(initialValue: balance) } var body: some View { - Form { - Section { - UIKitSearchBar(text: searchTextBinding) - } + VStack { + UIKitSearchBar(text: searchTextBinding) - Section { - List(filteredTransactions.sorted(by: { $0.valueDate.date > $1.valueDate.date } ), id: \.technicalId) { transaction in - AccountTransactionListItem(transaction) - } + HStack { + Text("\(filteredTransactions.count) transactions") + .styleAsDetail() + + Spacer() + + Text(presenter.formatAmount(amount: balanceOfFilteredTransactions)) + .styleAmount(amount: balanceOfFilteredTransactions) + } + .padding(.horizontal) + + List(filteredTransactions.sorted(by: { $0.valueDate.date > $1.valueDate.date } ), id: \.technicalId) { transaction in + AccountTransactionListItem(transaction) } } .showNavigationBarTitle(LocalizedStringKey(title)) @@ -53,6 +67,8 @@ struct AccountTransactionsDialog: View { private func filterTransactions(_ query: String) { self.filteredTransactions = presenter.searchAccountTransactions(query: query, transactions: allTransactions) + + self.balanceOfFilteredTransactions = query.isEmpty ? balanceOfAllTransactions : filteredTransactions.sumAmounts() } } @@ -61,6 +77,7 @@ struct AccountTransactionsDialog_Previews: PreviewProvider { static var previews: some View { AccountTransactionsDialog(title: previewBanks[0].displayName, transactions: [ 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)) } } diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/BankAccountListItem.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/BankAccountListItem.swift index abfb8597..4dc62a34 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/BankAccountListItem.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/BankAccountListItem.swift @@ -14,7 +14,7 @@ struct BankAccountListItem : View { Spacer() }.frame(height: 35) - NavigationLink(destination: AccountTransactionsDialog(title: account.displayName, transactions: account.bookedTransactions)) { + NavigationLink(destination: AccountTransactionsDialog(title: account.displayName, transactions: account.bookedTransactions, balance: account.balance)) { EmptyView() } } diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/BankListItem.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/BankListItem.swift index 896f4566..c0f442a5 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/BankListItem.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/BankListItem.swift @@ -17,7 +17,7 @@ struct BankListItem : View { Spacer() }.frame(height: 35) - NavigationLink(destination: AccountTransactionsDialog(title: bank.displayName, transactions: bank.accounts.flatMap { $0.bookedTransactions })) { + NavigationLink(destination: AccountTransactionsDialog(title: bank.displayName, transactions: bank.accounts.flatMap { $0.bookedTransactions }, balance: bank.balance)) { EmptyView() } }