mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-21 22:29:38 +02:00
feat: Add institution details to Plaid items (#1816)
* feat: Add institution details to Plaid items - Fetch and store institution URL, ID, and primary color for Plaid items - Update PlaidItem model to retrieve and save institution metadata - Add new method in Plaid provider to get institution details - Update account logo view to use institution domain for logo generation * Add institution domain method to Account model - Extract institution domain logic from view to Account model - Simplify logo view by using new institution_domain method - Improve code reusability and separation of concerns
This commit is contained in:
parent
df5f4c83fe
commit
7ba9063e04
7 changed files with 46 additions and 6 deletions
|
@ -32,6 +32,11 @@ class Account < ApplicationRecord
|
||||||
|
|
||||||
accepts_nested_attributes_for :accountable, update_only: true
|
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
|
class << self
|
||||||
def by_group(period: Period.all, currency: Money.default_currency.iso_code)
|
def by_group(period: Period.all, currency: Money.default_currency.iso_code)
|
||||||
grouped_accounts = { assets: ValueGroup.new("Assets", currency), liabilities: ValueGroup.new("Liabilities", currency) }
|
grouped_accounts = { assets: ValueGroup.new("Assets", currency), liabilities: ValueGroup.new("Liabilities", currency) }
|
||||||
|
|
|
@ -62,6 +62,20 @@ class PlaidItem < ApplicationRecord
|
||||||
item = plaid_provider.get_item(access_token).item
|
item = plaid_provider.get_item(access_token).item
|
||||||
update!(available_products: item.available_products, billed_products: item.billed_products)
|
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
|
fetched_accounts = plaid_provider.get_item_accounts(self).accounts
|
||||||
data[:accounts] = fetched_accounts || []
|
data[:accounts] = fetched_accounts || []
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,17 @@ class Provider::Plaid
|
||||||
response.liabilities
|
response.liabilities
|
||||||
end
|
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
|
private
|
||||||
TransactionSyncResponse = Struct.new :added, :modified, :removed, :cursor, keyword_init: true
|
TransactionSyncResponse = Struct.new :added, :modified, :removed, :cursor, keyword_init: true
|
||||||
InvestmentsResponse = Struct.new :holdings, :transactions, :securities, keyword_init: true
|
InvestmentsResponse = Struct.new :holdings, :transactions, :securities, keyword_init: true
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
<%= turbo_frame_tag dom_id(account) do %>
|
<%= turbo_frame_tag dom_id(account) do %>
|
||||||
<div class="p-4 flex items-center justify-between gap-3 group/account">
|
<div class="p-4 flex items-center justify-between gap-3 group/account">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="w-8 h-8 flex items-center justify-center rounded-full text-xs font-medium <%= account.is_active ? "bg-blue-500/10 text-blue-500" : "bg-gray-500/10 text-gray-500" %>">
|
<%= render "accounts/logo", account: account, size: "md" %>
|
||||||
<%= account.name[0].upcase %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<% if account.scheduled_for_deletion? %>
|
<% if account.scheduled_for_deletion? %>
|
||||||
|
|
|
@ -7,8 +7,10 @@
|
||||||
"full" => "w-full h-full"
|
"full" => "w-full h-full"
|
||||||
} %>
|
} %>
|
||||||
|
|
||||||
<% if account.logo.attached? %>
|
<% if account.plaid_account_id? && account.institution_domain.present? %>
|
||||||
<%= image_tag account.logo, class: size_classes[size] %>
|
<%= 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 %>
|
<% else %>
|
||||||
<%= circle_logo(account.name, hex: account.accountable.color, size: size) %>
|
<%= circle_logo(account.name, hex: account.accountable.color, size: size) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -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
|
5
db/schema.rb
generated
5
db/schema.rb
generated
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pgcrypto"
|
enable_extension "pgcrypto"
|
||||||
enable_extension "plpgsql"
|
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.string "billed_products", default: [], array: true
|
||||||
t.datetime "last_synced_at"
|
t.datetime "last_synced_at"
|
||||||
t.string "plaid_region", default: "us", null: false
|
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"
|
t.index ["family_id"], name: "index_plaid_items_on_family_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue