1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-06 22:15:20 +02:00
Maybe/app/models/plaid_item/importer.rb
2025-05-24 18:46:40 -04:00

57 lines
1.8 KiB
Ruby

class PlaidItem::Importer
def initialize(plaid_item, plaid_provider:)
@plaid_item = plaid_item
@plaid_provider = plaid_provider
end
def import
fetch_and_import_item_data
fetch_and_import_accounts_data
rescue Plaid::ApiError => e
handle_plaid_error(e)
end
private
attr_reader :plaid_item, :plaid_provider
# All errors that should halt the import should be re-raised after handling
# These errors will propagate up to the Sync record and mark it as failed.
def handle_plaid_error(error)
error_body = JSON.parse(error.response_body)
case error_body["error_code"]
when "ITEM_LOGIN_REQUIRED"
plaid_item.update!(status: :requires_update)
else
raise error
end
end
def fetch_and_import_item_data
item_data = plaid_provider.get_item(plaid_item.access_token).item
institution_data = plaid_provider.get_institution(item_data.institution_id).institution
plaid_item.upsert_plaid_snapshot!(item_data)
plaid_item.upsert_plaid_institution_snapshot!(institution_data)
end
def fetch_and_import_accounts_data
snapshot = PlaidItem::AccountsSnapshot.new(plaid_item, plaid_provider: plaid_provider)
PlaidItem.transaction do
snapshot.accounts.each do |raw_account|
plaid_account = plaid_item.plaid_accounts.find_or_initialize_by(
plaid_id: raw_account.account_id
)
PlaidAccount::Importer.new(
plaid_account,
account_snapshot: snapshot.get_account_data(raw_account.account_id)
).import
end
# Once we know all data has been imported, save the cursor to avoid re-fetching the same data next time
plaid_item.update!(next_cursor: snapshot.transactions_cursor)
end
end
end