From 49a0d32f6fecd8cab5003f54fdf161784bab245b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20K=C3=B6tte?= Date: Sat, 13 Jul 2024 15:32:50 -0700 Subject: [PATCH] Allow dynamic specification of account for more transaction types (#258) --- .../LedgerLookup.swift | 9 +++++-- .../WealthsimpleLedgerMapper.swift | 2 +- .../LedgerLookupTests.swift | 25 +++++++++---------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Sources/SwiftBeanCountWealthsimpleMapper/LedgerLookup.swift b/Sources/SwiftBeanCountWealthsimpleMapper/LedgerLookup.swift index fb7be60..7fadcc1 100644 --- a/Sources/SwiftBeanCountWealthsimpleMapper/LedgerLookup.swift +++ b/Sources/SwiftBeanCountWealthsimpleMapper/LedgerLookup.swift @@ -99,8 +99,13 @@ struct LedgerLookup { key = MetaDataKeys.rounding } guard let name = ledger.accounts.first(where: { accountTypes.contains($0.name.accountType) && $0.metaData[key]?.contains(account.number) ?? false })?.name else { - if case .transactionType(.paymentSpend) = type { - return WealthsimpleLedgerMapper.fallbackExpenseAccountName + if case let .transactionType(transactionType) = type { + switch transactionType { + case .onlineBillPayment, .deposit, .paymentSpend, .transferIn, .transferOut, .paymentTransferIn, .paymentTransferOut, .withdrawal: + return WealthsimpleLedgerMapper.fallbackExpenseAccountName + default: + throw WealthsimpleConversionError.missingAccount(key, account.number, accountTypes.map { $0.rawValue }.joined(separator: ", or ")) + } } throw WealthsimpleConversionError.missingAccount(key, account.number, accountTypes.map { $0.rawValue }.joined(separator: ", or ")) } diff --git a/Sources/SwiftBeanCountWealthsimpleMapper/WealthsimpleLedgerMapper.swift b/Sources/SwiftBeanCountWealthsimpleMapper/WealthsimpleLedgerMapper.swift index 865ca43..c54b958 100644 --- a/Sources/SwiftBeanCountWealthsimpleMapper/WealthsimpleLedgerMapper.swift +++ b/Sources/SwiftBeanCountWealthsimpleMapper/WealthsimpleLedgerMapper.swift @@ -19,7 +19,7 @@ public struct WealthsimpleLedgerMapper { // swiftlint:disable:this type_body_len /// Fallback account for payments if not account with the correct meta data could be found /// - /// Only used for transaction type payment spend + /// Only used for certain transaction types public static let fallbackExpenseAccountName = try! AccountName("Expenses:TODO") // swiftlint:disable:this force_try /// Payee used for fee transactions diff --git a/Tests/SwiftBeanCountWealthsimpleMapperTests/LedgerLookupTests.swift b/Tests/SwiftBeanCountWealthsimpleMapperTests/LedgerLookupTests.swift index 67b0201..6f91172 100644 --- a/Tests/SwiftBeanCountWealthsimpleMapperTests/LedgerLookupTests.swift +++ b/Tests/SwiftBeanCountWealthsimpleMapperTests/LedgerLookupTests.swift @@ -13,12 +13,17 @@ struct TestAccount: Wealthsimple.Account { final class LedgerLookupTests: XCTestCase { private let accountName = try! AccountName("Assets:Test") // swiftlint:disable:this force_try + private var ledger = Ledger() + private var ledgerLookup: LedgerLookup! + + override func setUpWithError() throws { + ledger = Ledger() + ledgerLookup = LedgerLookup(ledger) + } func testLedgerAccountCommoditySymbol() throws { let name2 = try AccountName("Assets:Test1") let symbol = "CAD" - let ledger = Ledger() - var ledgerLookup = LedgerLookup(ledger) // account does not exist XCTAssertNil(ledgerLookup.ledgerAccountCommoditySymbol(of: accountName)) @@ -38,8 +43,6 @@ final class LedgerLookupTests: XCTestCase { func testLedgerAccountNameOf() throws { let account = TestAccount(number: "abc") - let ledger = Ledger() - var ledgerLookup = LedgerLookup(ledger) // not found assert( @@ -65,8 +68,6 @@ final class LedgerLookupTests: XCTestCase { } func testLedgerAccountNameFor() throws { - let ledger = Ledger() - var ledgerLookup = LedgerLookup(ledger) var number = "abc123" // fallback for payment spend @@ -76,6 +77,8 @@ final class LedgerLookupTests: XCTestCase { // not found assert(try ledgerLookup.ledgerAccountName(for: .rounding, in: TestAccount(number: number), ofType: [.income]), throws: WealthsimpleConversionError.missingAccount(MetaDataKeys.rounding, number, "Income")) + assert(try ledgerLookup.ledgerAccountName(for: .transactionType(.dividend), in: TestAccount(number: number), ofType: [.income]), + throws: WealthsimpleConversionError.missingAccount("\(MetaDataKeys.prefix)\(TransactionType.dividend)", number, "Income")) // rounding try ledger.add(Account(name: accountName, metaData: [MetaDataKeys.rounding: number])) @@ -112,7 +115,6 @@ final class LedgerLookupTests: XCTestCase { } func testDoesTransactionExistInLedger() { - let ledger = Ledger() var metaData = TransactionMetaData(date: Date(), metaData: [MetaDataKeys.id: "abc"]) var transaction = Transaction(metaData: metaData, postings: []) ledger.add(transaction) @@ -147,11 +149,10 @@ final class LedgerLookupTests: XCTestCase { } func testDoesPriceExistInLedger() throws { - let ledger = Ledger() let date = Date() var price = try Price(date: date, commoditySymbol: "CAD", amount: Amount(number: Decimal(1), commoditySymbol: "EUR")) try ledger.add(price) - let ledgerLookup = LedgerLookup(ledger) + ledgerLookup = LedgerLookup(ledger) // same price XCTAssert(ledgerLookup.doesPriceExistInLedger(price)) @@ -170,11 +171,10 @@ final class LedgerLookupTests: XCTestCase { } func testDoesBalanceExistInLedger() throws { - let ledger = Ledger() let date = Date() var balance = Balance(date: date, accountName: accountName, amount: Amount(number: Decimal(1), commoditySymbol: "USD")) ledger.add(balance) - let ledgerLookup = LedgerLookup(ledger) + ledgerLookup = LedgerLookup(ledger) // same balance XCTAssert(ledgerLookup.doesBalanceExistInLedger(balance)) @@ -197,10 +197,9 @@ final class LedgerLookupTests: XCTestCase { } func testCommoditySymbolForAssetSymbol() throws { - let ledger = Ledger() var commodity = Commodity(symbol: "EUR") try ledger.add(commodity) - var ledgerLookup = LedgerLookup(ledger) + ledgerLookup = LedgerLookup(ledger) // not existing assert(