Refactor Plaid transaction type mapping and improve label handling

- Updated `PLAID_TYPE_TO_LABEL` in `TransactionsProcessor` to consolidate labels ("Cancel" and "Cash" now mapped to "Other").
- Adjusted `label_from_plaid_type` to return "Other" as the default fallback.
- Enhanced tests to include additional valid activity labels and ensure label consistency.
- Minor fixes to locale keys for transaction views.
This commit is contained in:
Josh Waldrep
2026-01-12 16:04:53 -05:00
parent 2f20d715a4
commit 308a4ab048
4 changed files with 28 additions and 22 deletions

View File

@@ -2,11 +2,12 @@ class PlaidAccount::Investments::TransactionsProcessor
SecurityNotFoundError = Class.new(StandardError)
# Map Plaid investment transaction types to activity labels
# All values must be valid Transaction::ACTIVITY_LABELS
PLAID_TYPE_TO_LABEL = {
"buy" => "Buy",
"sell" => "Sell",
"cancel" => "Cancelled",
"cash" => "Cash",
"cancel" => "Other",
"cash" => "Other",
"fee" => "Fee",
"transfer" => "Transfer",
"dividend" => "Dividend",
@@ -92,7 +93,7 @@ class PlaidAccount::Investments::TransactionsProcessor
def label_from_plaid_type(transaction)
plaid_type = transaction["type"]&.downcase
PLAID_TYPE_TO_LABEL[plaid_type] || plaid_type&.titleize
PLAID_TYPE_TO_LABEL[plaid_type] || "Other"
end
def transactions

View File

@@ -17,7 +17,7 @@ class Transaction < ApplicationRecord
cc_payment: "cc_payment", # A CC payment, excluded from budget analytics (CC payments offset the sum of expense transactions)
loan_payment: "loan_payment", # A payment to a Loan account, treated as an expense in budgets
one_time: "one_time", # A one-time expense/income, excluded from budget analytics
investment_contribution: "investment_contribution" # Transfer to investment/crypto account, included in budget as investment expense
investment_contribution: "investment_contribution" # Transfer to investment/crypto account, excluded from budget analytics
}
# All valid investment activity labels (for UI dropdown)

View File

@@ -51,25 +51,24 @@ en:
withdrawal: Withdrawal
exchange: Exchange
other: Other
mark_recurring: Mark as Recurring
mark_recurring_subtitle: Track this as a recurring transaction. Amount variance is automatically calculated from past 6 months of similar transactions.
mark_recurring_title: Recurring Transaction
merchant_label: Merchant
name_label: Name
nature: Type
none: "(none)"
note_label: Notes
note_placeholder: Enter a note
overview: Overview
settings: Settings
tags_label: Tags
uncategorized: "(uncategorized)"
potential_duplicate_title: Possible duplicate detected
potential_duplicate_description: This pending transaction may be the same as the posted transaction below. If so, merge them to avoid double-counting.
merge_duplicate: Yes, merge them
keep_both: No, keep both
loan_payment: Loan Payment
transfer: Transfer
mark_recurring: Mark as Recurring
mark_recurring_subtitle: Track this as a recurring transaction. Amount variance is automatically calculated from past 6 months of similar transactions.
mark_recurring_title: Recurring Transaction
merchant_label: Merchant
name_label: Name
nature: Type
none: "(none)"
note_label: Notes
note_placeholder: Enter a note
overview: Overview
settings: Settings
tags_label: Tags
uncategorized: "(uncategorized)"
potential_duplicate_title: Possible duplicate detected
potential_duplicate_description: This pending transaction may be the same as the posted transaction below. If so, merge them to avoid double-counting.
merge_duplicate: Yes, merge them
keep_both: No, keep both
transaction:
pending: Pending
pending_tooltip: Pending transaction — may change when posted

View File

@@ -41,7 +41,13 @@ class TransactionTest < ActiveSupport::TestCase
assert_includes Transaction::ACTIVITY_LABELS, "Sweep In"
assert_includes Transaction::ACTIVITY_LABELS, "Sweep Out"
assert_includes Transaction::ACTIVITY_LABELS, "Dividend"
assert_includes Transaction::ACTIVITY_LABELS, "Reinvestment"
assert_includes Transaction::ACTIVITY_LABELS, "Interest"
assert_includes Transaction::ACTIVITY_LABELS, "Fee"
assert_includes Transaction::ACTIVITY_LABELS, "Transfer"
assert_includes Transaction::ACTIVITY_LABELS, "Contribution"
assert_includes Transaction::ACTIVITY_LABELS, "Withdrawal"
assert_includes Transaction::ACTIVITY_LABELS, "Exchange"
assert_includes Transaction::ACTIVITY_LABELS, "Other"
end
end