diff --git a/app/models/account.rb b/app/models/account.rb index bef15abf..7b86a88e 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -32,6 +32,11 @@ class Account < ApplicationRecord accepts_nested_attributes_for :accountable, update_only: true + def institution_domain + return nil unless plaid_account&.plaid_item&.institution_url.present? + URI.parse(plaid_account.plaid_item.institution_url).host.gsub(/^www\./, "") + end + class << self def by_group(period: Period.all, currency: Money.default_currency.iso_code) grouped_accounts = { assets: ValueGroup.new("Assets", currency), liabilities: ValueGroup.new("Liabilities", currency) } diff --git a/app/models/plaid_item.rb b/app/models/plaid_item.rb index db6683d4..370493ca 100644 --- a/app/models/plaid_item.rb +++ b/app/models/plaid_item.rb @@ -62,6 +62,20 @@ class PlaidItem < ApplicationRecord item = plaid_provider.get_item(access_token).item update!(available_products: item.available_products, billed_products: item.billed_products) + # Fetch and store institution details + if item.institution_id.present? + begin + institution = plaid_provider.get_institution(item.institution_id) + update!( + institution_id: item.institution_id, + institution_url: institution.institution.url, + institution_color: institution.institution.primary_color + ) + rescue Plaid::ApiError => e + Rails.logger.warn("Error fetching institution details for item #{id}: #{e.message}") + end + end + fetched_accounts = plaid_provider.get_item_accounts(self).accounts data[:accounts] = fetched_accounts || [] diff --git a/app/models/provider/plaid.rb b/app/models/provider/plaid.rb index f12a077d..33f7af2f 100644 --- a/app/models/provider/plaid.rb +++ b/app/models/provider/plaid.rb @@ -143,6 +143,17 @@ class Provider::Plaid response.liabilities end + def get_institution(institution_id) + request = Plaid::InstitutionsGetByIdRequest.new({ + institution_id: institution_id, + country_codes: country_codes, + options: { + include_optional_metadata: true + } + }) + client.institutions_get_by_id(request) + end + private TransactionSyncResponse = Struct.new :added, :modified, :removed, :cursor, keyword_init: true InvestmentsResponse = Struct.new :holdings, :transactions, :securities, keyword_init: true diff --git a/app/views/accounts/_account.html.erb b/app/views/accounts/_account.html.erb index 8fcee360..3fc486b9 100644 --- a/app/views/accounts/_account.html.erb +++ b/app/views/accounts/_account.html.erb @@ -3,9 +3,7 @@ <%= turbo_frame_tag dom_id(account) do %>
-
"> - <%= account.name[0].upcase %> -
+ <%= render "accounts/logo", account: account, size: "md" %>
<% if account.scheduled_for_deletion? %> diff --git a/app/views/accounts/_logo.html.erb b/app/views/accounts/_logo.html.erb index 9036ad18..0d6b969d 100644 --- a/app/views/accounts/_logo.html.erb +++ b/app/views/accounts/_logo.html.erb @@ -7,8 +7,10 @@ "full" => "w-full h-full" } %> -<% if account.logo.attached? %> - <%= image_tag account.logo, class: size_classes[size] %> +<% if account.plaid_account_id? && account.institution_domain.present? %> + <%= image_tag "https://logo.synthfinance.com/#{account.institution_domain}", class: "rounded-full #{size_classes[size]}" %> +<% elsif account.logo.attached? %> + <%= image_tag account.logo, class: "rounded-full #{size_classes[size]}" %> <% else %> <%= circle_logo(account.name, hex: account.accountable.color, size: size) %> <% end %> diff --git a/db/migrate/20250206141452_add_institution_details_to_plaid_items.rb b/db/migrate/20250206141452_add_institution_details_to_plaid_items.rb new file mode 100644 index 00000000..77d19aae --- /dev/null +++ b/db/migrate/20250206141452_add_institution_details_to_plaid_items.rb @@ -0,0 +1,7 @@ +class AddInstitutionDetailsToPlaidItems < ActiveRecord::Migration[7.2] + def change + add_column :plaid_items, :institution_url, :string + add_column :plaid_items, :institution_id, :string + add_column :plaid_items, :institution_color, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 4a507949..89e53b87 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2025_01_31_171943) do +ActiveRecord::Schema[7.2].define(version: 2025_02_06_141452) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -517,6 +517,9 @@ ActiveRecord::Schema[7.2].define(version: 2025_01_31_171943) do t.string "billed_products", default: [], array: true t.datetime "last_synced_at" t.string "plaid_region", default: "us", null: false + t.string "institution_url" + t.string "institution_id" + t.string "institution_color" t.index ["family_id"], name: "index_plaid_items_on_family_id" end