Files
sure/app/models/plaid_entry/processor.rb
LPW 664c6c2b7c Pending detection, FX metadata, Pending UI badge. (#374)
* - Add support for `SIMPLEFIN_INCLUDE_PENDING` to control pending behavior via ENV.
- Enhance debug logging for SimpleFin API requests and raw payloads.
- Refine pending flag handling in `SimplefinEntry::Processor` based on provider data and inferred conditions.
- Improve FX metadata processing for transactions with currency mismatches.
- Add new tests for pending detection, FX metadata, and edge cases involving `posted` values.
- Add pending indicator UI to transaction view.

* Document pending transaction detection, storage, and UI behavior for SimpleFIN and Plaid integrations. Add debug flags for troubleshooting.

* Add `pending?` method to `Transaction` model, refactor UI indicator, and centralize SimpleFIN configuration

- Introduced `pending?` method in `Transaction` for unified pending state detection.
- Refactored transaction pending indicator in the UI to use `pending?` method.
- Centralized SimpleFIN configuration in initializer with ENV-backed toggles.
- Updated tests for `pending?` behavior and clarified docs for pending detection logic

* Add SimpleFIN debug and runtime flags to `.env.local.example` and `.env.test.example`

- Introduced `SIMPLEFIN_INCLUDE_PENDING` and `SIMPLEFIN_DEBUG_RAW` flags for controlling pending behavior and debugging.
- Updated example environment files with descriptions for new configuration options.

* Normalize formatting for `SIMPLEFIN_INCLUDE_PENDING` and `SIMPLEFIN_DEBUG_RAW` flags in `.env.local.example` and `.env.test.example`.

---------

Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
2025-12-19 23:24:48 +01:00

77 lines
1.8 KiB
Ruby

class PlaidEntry::Processor
# plaid_transaction is the raw hash fetched from Plaid API and converted to JSONB
def initialize(plaid_transaction, plaid_account:, category_matcher:)
@plaid_transaction = plaid_transaction
@plaid_account = plaid_account
@category_matcher = category_matcher
end
def process
import_adapter.import_transaction(
external_id: external_id,
amount: amount,
currency: currency,
date: date,
name: name,
source: "plaid",
category_id: matched_category&.id,
merchant: merchant,
extra: {
plaid: {
pending: plaid_transaction["pending"]
}
}
)
end
private
attr_reader :plaid_transaction, :plaid_account, :category_matcher
def import_adapter
@import_adapter ||= Account::ProviderImportAdapter.new(account)
end
def account
plaid_account.current_account
end
def external_id
plaid_transaction["transaction_id"]
end
def name
plaid_transaction["merchant_name"] || plaid_transaction["original_description"]
end
def amount
plaid_transaction["amount"]
end
def currency
plaid_transaction["iso_currency_code"]
end
def date
plaid_transaction["date"]
end
def detailed_category
plaid_transaction.dig("personal_finance_category", "detailed")
end
def matched_category
return nil unless detailed_category
@matched_category ||= category_matcher.match(detailed_category)
end
def merchant
@merchant ||= import_adapter.find_or_create_merchant(
provider_merchant_id: plaid_transaction["merchant_entity_id"],
name: plaid_transaction["merchant_name"],
source: "plaid",
website_url: plaid_transaction["website"],
logo_url: plaid_transaction["logo_url"]
)
end
end