From d29965c77ebaef60c4797701af8d5a76791f677c Mon Sep 17 00:00:00 2001 From: dankito Date: Sat, 18 Jul 2020 16:39:21 +0200 Subject: [PATCH] Implemented saving bank data with CoreData --- .../BankingiOSApp.xcodeproj/project.pbxproj | 24 +- .../BankingiOSApp/AppDelegate.swift | 19 +- .../BankingiOSApp.xcdatamodel/contents | 75 +++++- .../CoreDataBankingPersistence.swift | 82 +++++++ .../BankingiOSApp/persistence/Mapper.swift | 227 ++++++++++++++++++ 5 files changed, 405 insertions(+), 22 deletions(-) create mode 100644 ui/BankingiOSApp/BankingiOSApp/persistence/CoreDataBankingPersistence.swift create mode 100644 ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift diff --git a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj index ba381c6b..39663a30 100644 --- a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj +++ b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj @@ -22,9 +22,6 @@ 36BCF87324BB2706005BEC29 /* BankingUiSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36BCF87224BB2706005BEC29 /* BankingUiSwift.framework */; }; 36BCF87424BB2706005BEC29 /* BankingUiSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 36BCF87224BB2706005BEC29 /* BankingUiSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 36BCF87624BF114F005BEC29 /* UrlSessionWebClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF87524BF114F005BEC29 /* UrlSessionWebClient.swift */; }; - 36BCF87B24BFA87E005BEC29 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF87A24BFA87E005BEC29 /* Extensions.swift */; }; - 36BCF87F24BFAA7F005BEC29 /* TestEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF87E24BFAA7F005BEC29 /* TestEntity.swift */; }; - 36BCF88124BFAB4A005BEC29 /* DependendTestEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF88024BFAB4A005BEC29 /* DependendTestEntity.swift */; }; 36BCF88324C098BB005BEC29 /* BankListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF88224C098BB005BEC29 /* BankListItem.swift */; }; 36BCF88524C098C8005BEC29 /* BankAccountListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF88424C098C8005BEC29 /* BankAccountListItem.swift */; }; 36BCF88724C0A310005BEC29 /* PreviewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF88624C0A310005BEC29 /* PreviewData.swift */; }; @@ -32,6 +29,9 @@ 36BCF88B24C0BD2D005BEC29 /* AccountTransactionsDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF88A24C0BD2D005BEC29 /* AccountTransactionsDialog.swift */; }; 36BCF88D24C1C1EA005BEC29 /* TransferMoneyDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF88C24C1C1EA005BEC29 /* TransferMoneyDialog.swift */; }; 36BCF88F24C1DFF7005BEC29 /* SheetPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF88E24C1DFF7005BEC29 /* SheetPresenter.swift */; }; + 36BCF89124C25971005BEC29 /* CoreDataBankingPersistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF89024C25971005BEC29 /* CoreDataBankingPersistence.swift */; }; + 36BCF89324C25BC3005BEC29 /* Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF89224C25BC3005BEC29 /* Mapper.swift */; }; + 36BCF89524C31F02005BEC29 /* AppData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BCF89424C31F02005BEC29 /* AppData.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 */; }; @@ -97,9 +97,6 @@ 36BCF86F24BB0F8A005BEC29 /* fints4kBankingClient.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = fints4kBankingClient.framework; path = "../fints4kBankingClient/build/xcode-frameworks/fints4kBankingClient.framework"; sourceTree = ""; }; 36BCF87224BB2706005BEC29 /* BankingUiSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BankingUiSwift.framework; path = "../BankingUiNativeIntegration/build/xcode-frameworks/BankingUiSwift.framework"; sourceTree = ""; }; 36BCF87524BF114F005BEC29 /* UrlSessionWebClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlSessionWebClient.swift; sourceTree = ""; }; - 36BCF87A24BFA87E005BEC29 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; - 36BCF87E24BFAA7F005BEC29 /* TestEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestEntity.swift; sourceTree = ""; }; - 36BCF88024BFAB4A005BEC29 /* DependendTestEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DependendTestEntity.swift; sourceTree = ""; }; 36BCF88224C098BB005BEC29 /* BankListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankListItem.swift; sourceTree = ""; }; 36BCF88424C098C8005BEC29 /* BankAccountListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankAccountListItem.swift; sourceTree = ""; }; 36BCF88624C0A310005BEC29 /* PreviewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewData.swift; sourceTree = ""; }; @@ -107,6 +104,9 @@ 36BCF88A24C0BD2D005BEC29 /* AccountTransactionsDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTransactionsDialog.swift; sourceTree = ""; }; 36BCF88C24C1C1EA005BEC29 /* TransferMoneyDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransferMoneyDialog.swift; sourceTree = ""; }; 36BCF88E24C1DFF7005BEC29 /* SheetPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetPresenter.swift; sourceTree = ""; }; + 36BCF89024C25971005BEC29 /* CoreDataBankingPersistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataBankingPersistence.swift; sourceTree = ""; }; + 36BCF89224C25BC3005BEC29 /* Mapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mapper.swift; sourceTree = ""; }; + 36BCF89424C31F02005BEC29 /* AppData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppData.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; }; @@ -166,9 +166,9 @@ 36BCF87924BFA679005BEC29 /* persistence */ = { isa = PBXGroup; children = ( - 36BCF87A24BFA87E005BEC29 /* Extensions.swift */, - 36BCF87E24BFAA7F005BEC29 /* TestEntity.swift */, - 36BCF88024BFAB4A005BEC29 /* DependendTestEntity.swift */, + 36BCF89024C25971005BEC29 /* CoreDataBankingPersistence.swift */, + 36BCF89224C25BC3005BEC29 /* Mapper.swift */, + 36BCF89424C31F02005BEC29 /* AppData.swift */, ); path = persistence; sourceTree = ""; @@ -449,20 +449,20 @@ files = ( 36FC92DC24B3A4A0002B12E9 /* AccountsTab.swift in Sources */, 36BCF86E24BA691B005BEC29 /* DependencyInjector.swift in Sources */, + 36BCF89124C25971005BEC29 /* CoreDataBankingPersistence.swift in Sources */, 36FC92A124B39A05002B12E9 /* BankingiOSApp.xcdatamodeld in Sources */, + 36BCF89324C25BC3005BEC29 /* Mapper.swift in Sources */, 36FC92D724B3A3BA002B12E9 /* NSUrlWebClient.swift in Sources */, + 36BCF89524C31F02005BEC29 /* AppData.swift in Sources */, 36BCF88324C098BB005BEC29 /* BankListItem.swift in Sources */, - 36BCF87F24BFAA7F005BEC29 /* TestEntity.swift in Sources */, 36BCF88D24C1C1EA005BEC29 /* TransferMoneyDialog.swift in Sources */, 36E7BA1424B3D05C00757859 /* ViewExtensions.swift in Sources */, 36BCF88924C0A7D7005BEC29 /* Message.swift in Sources */, 36BCF86C24BA5E72005BEC29 /* DispatchQueueAsyncRunner.swift in Sources */, - 36BCF88124BFAB4A005BEC29 /* DependendTestEntity.swift in Sources */, 36BCF86324BA5097005BEC29 /* SwiftUiRouter.swift in Sources */, 36BCF88F24C1DFF7005BEC29 /* SheetPresenter.swift in Sources */, 36FC929C24B39A05002B12E9 /* AppDelegate.swift in Sources */, 36BCF88B24C0BD2D005BEC29 /* AccountTransactionsDialog.swift in Sources */, - 36BCF87B24BFA87E005BEC29 /* Extensions.swift in Sources */, 36BCF87624BF114F005BEC29 /* UrlSessionWebClient.swift in Sources */, 36FC92A324B39A05002B12E9 /* ContentView.swift in Sources */, 36BCF88724C0A310005BEC29 /* PreviewData.swift in Sources */, diff --git a/ui/BankingiOSApp/BankingiOSApp/AppDelegate.swift b/ui/BankingiOSApp/BankingiOSApp/AppDelegate.swift index 4b65a0dc..2f2b5907 100644 --- a/ui/BankingiOSApp/BankingiOSApp/AppDelegate.swift +++ b/ui/BankingiOSApp/BankingiOSApp/AppDelegate.swift @@ -6,23 +6,26 @@ import BankingUiSwift @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - override init() { + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + setupDI() + + return true + } + + func setupDI() { let appDataFolder = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, .userDomainMask, true).first ?? Bundle.main.resourceURL?.absoluteString ?? "" + let persistence = CoreDataBankingPersistence(persistentContainer: self.persistentContainer) + let dataFolder = URL(fileURLWithPath: "data", isDirectory: true, relativeTo: URL(fileURLWithPath: appDataFolder)) - let presenter = BankingPresenterSwift(dataFolder: dataFolder, router: SwiftUiRouter(), webClient: UrlSessionWebClient(), asyncRunner: DispatchQueueAsyncRunner()) + let presenter = BankingPresenterSwift(dataFolder: dataFolder, router: SwiftUiRouter(), webClient: UrlSessionWebClient(), persistence: persistence, asyncRunner: DispatchQueueAsyncRunner()) DependencyInjector.register(dependency: presenter) } - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - return true - } - // MARK: UISceneSession Lifecycle func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { diff --git a/ui/BankingiOSApp/BankingiOSApp/BankingiOSApp.xcdatamodeld/BankingiOSApp.xcdatamodel/contents b/ui/BankingiOSApp/BankingiOSApp/BankingiOSApp.xcdatamodeld/BankingiOSApp.xcdatamodel/contents index 50d2514e..99ab8aec 100644 --- a/ui/BankingiOSApp/BankingiOSApp/BankingiOSApp.xcdatamodeld/BankingiOSApp.xcdatamodel/contents +++ b/ui/BankingiOSApp/BankingiOSApp/BankingiOSApp.xcdatamodeld/BankingiOSApp.xcdatamodel/contents @@ -1,4 +1,75 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/CoreDataBankingPersistence.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/CoreDataBankingPersistence.swift new file mode 100644 index 00000000..d4e76b82 --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/persistence/CoreDataBankingPersistence.swift @@ -0,0 +1,82 @@ +import Foundation +import CoreData +import BankingUiSwift + + +class CoreDataBankingPersistence: BUCIBankingPersistence { + + private let persistentContainer: NSPersistentContainer + + private let mapper = Mapper() + + private var context: NSManagedObjectContext { + return persistentContainer.viewContext + } + + + init(persistentContainer: NSPersistentContainer) { + self.persistentContainer = persistentContainer + } + + + func saveOrUpdateAccount(customer: BUCCustomer, allCustomers: [BUCCustomer]) { + do { + let mapped = mapper.map(customer, context) + + context.insert(mapped) + + try context.save() + } catch { + print("Could not save Customer \(customer): \(error)") + } + } + + func readPersistedAccounts_() -> [BUCCustomer] { + var customers: [Customer] = [] + + do { + let request: NSFetchRequest = Customer.fetchRequest() + request.returnsObjectsAsFaults = false + + try customers = context.fetch(request) + } catch { + NSLog("Could not request Customers: \(error)") + } + + return customers.map( { mapper.map($0) } ) + } + + func deleteAccount(customer: BUCCustomer, allCustomers: [BUCCustomer]) { + do { + let mapped = mapper.map(customer, context) + + context.delete(mapped) + + try context.save() + } catch { + NSLog("Could not delete Customer \(customer): \(error)") + } + } + + func saveOrUpdateAccountTransactions(bankAccount: BUCBankAccount, transactions: [BUCAccountTransaction]) { + // TODO + } + + func saveUrlToFile(url: String, file: URL) { + // TODO + } + + + func deleteAll() { + do { + let request = NSFetchRequest(entityName: "Customer") + + let deleteAll = NSBatchDeleteRequest(fetchRequest: request) + + try context.execute(deleteAll) + } catch { + NSLog("Could not delete all Customers: \(error)") + } + } + +} diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift new file mode 100644 index 00000000..519bbd58 --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift @@ -0,0 +1,227 @@ +import Foundation +import CoreData +import BankingUiSwift + + +class Mapper { + + func map(_ customer: Customer) -> BUCCustomer { + let mapped = BUCCustomer(bankCode: map(customer.bankCode), customerId: map(customer.customerId), password: map(customer.password), finTsServerAddress: map(customer.finTsServerAddress), bankName: map(customer.bankName), bic: map(customer.bic), customerName: map(customer.customerName), userId: map(customer.userId), iconUrl: customer.iconUrl, accounts: []) + + mapped.accounts = map(mapped, customer.accounts as? Set) + + return mapped + } + + func map(_ customer: BUCCustomer, _ context: NSManagedObjectContext) -> Customer { + let mapped = Customer(context: context) + + mapped.bankCode = customer.bankCode + mapped.customerId = customer.customerId + mapped.password = customer.password + mapped.finTsServerAddress = customer.finTsServerAddress + mapped.bankName = customer.bankName + mapped.bic = customer.bic + mapped.customerName = customer.customerName + mapped.userId = customer.userId + mapped.iconUrl = customer.iconUrl + + mapped.accounts = NSSet(array: map(mapped, customer.accounts, context)) + + return mapped + } + + + func map(_ customer: BUCCustomer, _ accounts: Set?) -> [BUCBankAccount] { + return accounts?.map( { map(customer, $0) } ) ?? [] + } + + func map(_ customer: BUCCustomer, _ account: BankAccount) -> BUCBankAccount { + let mapped = BUCBankAccount(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, bookedAccountTransactions: []) + + mapped.bookedTransactions = map(mapped, account.transactions as? Set) + + return mapped + } + + func map(_ customer: Customer, _ accounts: [BUCBankAccount], _ context: NSManagedObjectContext) -> [BankAccount] { + return accounts.map( { map(customer, $0, context) } ) + } + + func map(_ customer: Customer, _ account: BUCBankAccount, _ context: NSManagedObjectContext) -> BankAccount { + let mapped = BankAccount(context: context) + + mapped.customer = customer + mapped.identifier = account.identifier + mapped.accountHolderName = account.accountHolderName + mapped.iban = account.iban + mapped.subAccountNumber = account.subAccountNumber + mapped.customerId = account.customerId + mapped.balance = account.balance.decimal + mapped.currency = account.currency + mapped.type = map(account.type) + mapped.productName = account.productName + mapped.accountLimit = account.accountLimit + mapped.lastRetrievedTransactionsTimestamp = account.lastRetrievedTransactionsTimestamp?.date + mapped.supportsRetrievingAccountTransactions = account.supportsRetrievingAccountTransactions + mapped.supportsRetrievingBalance = account.supportsRetrievingBalance + mapped.supportsTransferringMoney = account.supportsTransferringMoney + mapped.supportsInstantPaymentMoneyTransfer = account.supportsInstantPaymentMoneyTransfer + + mapped.transactions = NSSet(array: map(mapped, account.bookedTransactions, context)) + + return mapped + } + + + func map(_ type: BUCBankAccountType) -> String { + return type.name + } + + func map(_ type: String?) -> BUCBankAccountType { + switch type { + case BUCBankAccountType.girokonto.name: + return BUCBankAccountType.girokonto + case BUCBankAccountType.sparkonto.name: + return BUCBankAccountType.sparkonto + case BUCBankAccountType.festgeldkonto.name: + return BUCBankAccountType.festgeldkonto + case BUCBankAccountType.wertpapierdepot.name: + return BUCBankAccountType.wertpapierdepot + case BUCBankAccountType.darlehenskonto.name: + return BUCBankAccountType.darlehenskonto + case BUCBankAccountType.kreditkartenkonto.name: + return BUCBankAccountType.kreditkartenkonto + case BUCBankAccountType.fondsdepot.name: + return BUCBankAccountType.fondsdepot + case BUCBankAccountType.bausparvertrag.name: + return BUCBankAccountType.bausparvertrag + case BUCBankAccountType.versicherungsvertrag.name: + return BUCBankAccountType.versicherungsvertrag + case BUCBankAccountType.sonstige.name: + return BUCBankAccountType.sonstige + default: + return BUCBankAccountType.girokonto + } + } + + + func map(_ account: BUCBankAccount, _ transactions: Set?) -> [BUCAccountTransaction] { + return transactions?.map( {map(account, $0) } ) ?? [] + } + + func map(_ account: BUCBankAccount, _ transaction: AccountTransaction) -> BUCAccountTransaction { + return BUCAccountTransaction(bankAccount: account, amount: map(transaction.amount), currency: map(transaction.currency), unparsedUsage: map(transaction.unparsedUsage), bookingDate: map(transaction.bookingDate), otherPartyName: transaction.otherPartyName, otherPartyBankCode: transaction.otherPartyBankCode, otherPartyAccountId: transaction.otherPartyAccountId, bookingText: transaction.bookingText, valueDate: map(transaction.valueDate), statementNumber: Int32(transaction.statementNumber), sequenceNumber: map(transaction.sequenceNumber), openingBalance: map(transaction.openingBalance), closingBalance: map(transaction.closingBalance), endToEndReference: transaction.endToEndReference, customerReference: transaction.customerReference, mandateReference: transaction.mandateReference, creditorIdentifier: transaction.creditorIdentifier, originatorsIdentificationCode: transaction.originatorsIdentificationCode, compensationAmount: transaction.compensationAmount, originalAmount: transaction.originalAmount, sepaUsage: transaction.sepaUsage, deviantOriginator: transaction.deviantOriginator, deviantRecipient: transaction.deviantRecipient, usageWithNoSpecialType: transaction.usageWithNoSpecialType, primaNotaNumber: transaction.primaNotaNumber, textKeySupplement: transaction.textKeySupplement, currencyType: transaction.currencyType, bookingKey: map(transaction.bookingKey), referenceForTheAccountOwner: map(transaction.referenceForTheAccountOwner), referenceOfTheAccountServicingInstitution: transaction.referenceOfTheAccountServicingInstitution, supplementaryDetails: transaction.supplementaryDetails, transactionReferenceNumber: map(transaction.transactionReferenceNumber), relatedReferenceNumber: transaction.relatedReferenceNumber) + } + + + func map(_ account: BankAccount, _ transactions: [BUCAccountTransaction], _ context: NSManagedObjectContext) -> [AccountTransaction] { + return transactions.map( {map(account, $0, context) } ) + } + + func map(_ account: BankAccount, _ transaction: BUCAccountTransaction, _ context: NSManagedObjectContext) -> AccountTransaction { + let mapped = AccountTransaction(context: context) + + mapped.account = account + + mapped.amount = map(transaction.amount) + mapped.currency = transaction.currency + mapped.unparsedUsage = transaction.unparsedUsage + mapped.bookingDate = map(transaction.bookingDate) + mapped.otherPartyName = transaction.otherPartyName + mapped.otherPartyBankCode = transaction.otherPartyBankCode + mapped.otherPartyAccountId = transaction.otherPartyAccountId + mapped.bookingText = transaction.bookingText + mapped.valueDate = map(transaction.valueDate) + + mapped.statementNumber = transaction.statementNumber + mapped.sequenceNumber = map(transaction.sequenceNumber) ?? 0 // TODO: why doesn't it accept Int32? ? + mapped.openingBalance = mapOptional(transaction.openingBalance) + mapped.closingBalance = mapOptional(transaction.closingBalance) + + mapped.endToEndReference = transaction.endToEndReference + mapped.customerReference = transaction.customerReference + mapped.mandateReference = transaction.mandateReference + mapped.creditorIdentifier = transaction.creditorIdentifier + mapped.originatorsIdentificationCode = transaction.originatorsIdentificationCode + mapped.compensationAmount = transaction.compensationAmount + mapped.originalAmount = transaction.originalAmount + mapped.sepaUsage = transaction.sepaUsage + mapped.deviantOriginator = transaction.deviantOriginator + mapped.deviantRecipient = transaction.deviantRecipient + mapped.usageWithNoSpecialType = transaction.usageWithNoSpecialType + mapped.primaNotaNumber = transaction.primaNotaNumber + mapped.textKeySupplement = transaction.textKeySupplement + + mapped.currencyType = transaction.currencyType + mapped.bookingKey = transaction.bookingKey + mapped.referenceForTheAccountOwner = transaction.referenceForTheAccountOwner + mapped.referenceOfTheAccountServicingInstitution = transaction.referenceOfTheAccountServicingInstitution + mapped.supplementaryDetails = transaction.supplementaryDetails + + mapped.transactionReferenceNumber = transaction.transactionReferenceNumber + mapped.relatedReferenceNumber = transaction.relatedReferenceNumber + + return mapped + } + + + func map(_ date: Date?) -> CommonDate { + if let date = date { + return CommonDate(date: date) + } + + return CommonDate(millisSinceEpoch: 0) + } + + func map(_ date: CommonDate) -> Date { + return date.date + } + + + func map(_ decimal: NSDecimalNumber?) -> CommonBigDecimal { + if let decimal = decimal { + return map(decimal) + } + + return CommonBigDecimal(double: 0) + } + + func map(_ decimal: NSDecimalNumber) -> CommonBigDecimal { + return CommonBigDecimal(decimal_: decimal) + } + + func mapOptional(_ decimal: CommonBigDecimal?) -> NSDecimalNumber? { + if let decimal = decimal { + return map(decimal) + } + + return nil + } + + func map(_ decimal: CommonBigDecimal) -> NSDecimalNumber { + return decimal.decimal + } + + + func map(_ int: Int32?) -> KotlinInt? { + if let int = int { + return KotlinInt(int: int) + } + + return nil + } + + func map(_ int: KotlinInt?) -> Int32? { + if let int = int { + return Int32(int) + } + + return nil + } + + func map(_ string: String?) -> String { + return string ?? "" + } + +}