From a947db92b2b0ca03daffb18be4cd6236a72a1ae3 Mon Sep 17 00:00:00 2001 From: Zach Gollwitzer Date: Thu, 20 Jun 2024 07:26:25 -0400 Subject: [PATCH] Account namespace updates: part 1 (#893) * Rename accountable types * Merge conflicts * Fix broken tests * Add back sidebar changes --- app/helpers/accounts_helper.rb | 16 ++-- app/models/account/credit.rb | 3 - app/models/account/crypto.rb | 3 - app/models/account/depository.rb | 3 - app/models/account/loan.rb | 3 - app/models/account/other_asset.rb | 3 - app/models/account/other_liability.rb | 3 - app/models/account/property.rb | 3 - app/models/account/vehicle.rb | 3 - app/models/concerns/accountable.rb | 17 +--- app/models/credit_card.rb | 3 + app/models/crypto.rb | 3 + app/models/depository.rb | 3 + app/models/{account => }/investment.rb | 2 +- app/models/loan.rb | 3 + app/models/other_asset.rb | 3 + app/models/other_liability.rb | 3 + app/models/property.rb | 3 + app/models/vehicle.rb | 3 + ..._credit.html.erb => _credit_card.html.erb} | 0 .../accounts/account/_investment.html.erb | 2 +- app/views/accounts/new.html.erb | 19 ++-- app/views/layouts/_sidebar.html.erb | 2 +- config/routes.rb | 17 +++- ...0240619125949_rename_accountable_tables.rb | 87 +++++++++++++++++ db/schema.rb | 94 +++++++++---------- lib/tasks/demo_data.rake | 32 +++---- test/controllers/accounts_controller_test.rb | 4 +- test/fixtures/accounts.yml | 22 ++--- .../{account/credits.yml => credit_cards.yml} | 0 test/fixtures/{account => }/cryptos.yml | 0 test/fixtures/{account => }/depositories.yml | 0 test/fixtures/{account => }/investments.yml | 0 test/fixtures/{account => }/loans.yml | 0 test/fixtures/{account => }/other_assets.yml | 0 .../{account => }/other_liabilities.yml | 0 test/fixtures/{account => }/properties.yml | 0 test/fixtures/{account => }/vehicles.yml | 0 test/models/account/depository_test.rb | 7 -- test/models/account/investment_test.rb | 7 -- test/models/account/other_asset_test.rb | 7 -- test/models/account/other_liability_test.rb | 7 -- test/models/account/property_test.rb | 7 -- test/models/account_test.rb | 16 ++-- .../credit_test.rb => credit_card_test.rb} | 2 +- test/models/{account => }/crypto_test.rb | 2 +- test/models/depository_test.rb | 7 ++ test/models/investment_test.rb | 7 ++ test/models/{account => }/loan_test.rb | 2 +- test/models/other_asset_test.rb | 7 ++ test/models/other_liability_test.rb | 7 ++ test/models/property_test.rb | 7 ++ test/models/{account => }/vehicle_test.rb | 2 +- test/system/accounts_test.rb | 77 +++++++++++++++ 54 files changed, 349 insertions(+), 184 deletions(-) delete mode 100644 app/models/account/credit.rb delete mode 100644 app/models/account/crypto.rb delete mode 100644 app/models/account/depository.rb delete mode 100644 app/models/account/loan.rb delete mode 100644 app/models/account/other_asset.rb delete mode 100644 app/models/account/other_liability.rb delete mode 100644 app/models/account/property.rb delete mode 100644 app/models/account/vehicle.rb create mode 100644 app/models/credit_card.rb create mode 100644 app/models/crypto.rb create mode 100644 app/models/depository.rb rename app/models/{account => }/investment.rb (89%) create mode 100644 app/models/loan.rb create mode 100644 app/models/other_asset.rb create mode 100644 app/models/other_liability.rb create mode 100644 app/models/property.rb create mode 100644 app/models/vehicle.rb rename app/views/accounts/account/{_credit.html.erb => _credit_card.html.erb} (100%) create mode 100644 db/migrate/20240619125949_rename_accountable_tables.rb rename test/fixtures/{account/credits.yml => credit_cards.yml} (100%) rename test/fixtures/{account => }/cryptos.yml (100%) rename test/fixtures/{account => }/depositories.yml (100%) rename test/fixtures/{account => }/investments.yml (100%) rename test/fixtures/{account => }/loans.yml (100%) rename test/fixtures/{account => }/other_assets.yml (100%) rename test/fixtures/{account => }/other_liabilities.yml (100%) rename test/fixtures/{account => }/properties.yml (100%) rename test/fixtures/{account => }/vehicles.yml (100%) delete mode 100644 test/models/account/depository_test.rb delete mode 100644 test/models/account/investment_test.rb delete mode 100644 test/models/account/other_asset_test.rb delete mode 100644 test/models/account/other_liability_test.rb delete mode 100644 test/models/account/property_test.rb rename test/models/{account/credit_test.rb => credit_card_test.rb} (59%) rename test/models/{account => }/crypto_test.rb (59%) create mode 100644 test/models/depository_test.rb create mode 100644 test/models/investment_test.rb rename test/models/{account => }/loan_test.rb (60%) create mode 100644 test/models/other_asset_test.rb create mode 100644 test/models/other_liability_test.rb create mode 100644 test/models/property_test.rb rename test/models/{account => }/vehicle_test.rb (59%) create mode 100644 test/system/accounts_test.rb diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb index 0907f0ac..54ec09fa 100644 --- a/app/helpers/accounts_helper.rb +++ b/app/helpers/accounts_helper.rb @@ -27,14 +27,14 @@ module AccountsHelper def class_mapping(accountable_type) { - "Account::Credit" => { text: "text-red-500", bg: "bg-red-500", bg_transparent: "bg-red-500/10", fill: "fill-red-500", hex: "#F13636" }, - "Account::Loan" => { text: "text-fuchsia-500", bg: "bg-fuchsia-500", bg_transparent: "bg-fuchsia-500/10", fill: "fill-fuchsia-500", hex: "#D444F1" }, - "Account::OtherLiability" => { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" }, - "Account::Depository" => { text: "text-violet-500", bg: "bg-violet-500", bg_transparent: "bg-violet-500/10", fill: "fill-violet-500", hex: "#875BF7" }, - "Account::Investment" => { text: "text-blue-600", bg: "bg-blue-600", bg_transparent: "bg-blue-600/10", fill: "fill-blue-600", hex: "#1570EF" }, - "Account::OtherAsset" => { text: "text-green-500", bg: "bg-green-500", bg_transparent: "bg-green-500/10", fill: "fill-green-500", hex: "#12B76A" }, - "Account::Property" => { text: "text-cyan-500", bg: "bg-cyan-500", bg_transparent: "bg-cyan-500/10", fill: "fill-cyan-500", hex: "#06AED4" }, - "Account::Vehicle" => { text: "text-pink-500", bg: "bg-pink-500", bg_transparent: "bg-pink-500/10", fill: "fill-pink-500", hex: "#F23E94" } + "CreditCard" => { text: "text-red-500", bg: "bg-red-500", bg_transparent: "bg-red-500/10", fill: "fill-red-500", hex: "#F13636" }, + "Loan" => { text: "text-fuchsia-500", bg: "bg-fuchsia-500", bg_transparent: "bg-fuchsia-500/10", fill: "fill-fuchsia-500", hex: "#D444F1" }, + "OtherLiability" => { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" }, + "Depository" => { text: "text-violet-500", bg: "bg-violet-500", bg_transparent: "bg-violet-500/10", fill: "fill-violet-500", hex: "#875BF7" }, + "Investment" => { text: "text-blue-600", bg: "bg-blue-600", bg_transparent: "bg-blue-600/10", fill: "fill-blue-600", hex: "#1570EF" }, + "OtherAsset" => { text: "text-green-500", bg: "bg-green-500", bg_transparent: "bg-green-500/10", fill: "fill-green-500", hex: "#12B76A" }, + "Property" => { text: "text-cyan-500", bg: "bg-cyan-500", bg_transparent: "bg-cyan-500/10", fill: "fill-cyan-500", hex: "#06AED4" }, + "Vehicle" => { text: "text-pink-500", bg: "bg-pink-500", bg_transparent: "bg-pink-500/10", fill: "fill-pink-500", hex: "#F23E94" } }.fetch(accountable_type, { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" }) end end diff --git a/app/models/account/credit.rb b/app/models/account/credit.rb deleted file mode 100644 index 06e91afc..00000000 --- a/app/models/account/credit.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Account::Credit < ApplicationRecord - include Accountable -end diff --git a/app/models/account/crypto.rb b/app/models/account/crypto.rb deleted file mode 100644 index 8aae9a6d..00000000 --- a/app/models/account/crypto.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Account::Crypto < ApplicationRecord - include Accountable -end diff --git a/app/models/account/depository.rb b/app/models/account/depository.rb deleted file mode 100644 index b7d4cb30..00000000 --- a/app/models/account/depository.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Account::Depository < ApplicationRecord - include Accountable -end diff --git a/app/models/account/loan.rb b/app/models/account/loan.rb deleted file mode 100644 index 71c72d92..00000000 --- a/app/models/account/loan.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Account::Loan < ApplicationRecord - include Accountable -end diff --git a/app/models/account/other_asset.rb b/app/models/account/other_asset.rb deleted file mode 100644 index b4f638da..00000000 --- a/app/models/account/other_asset.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Account::OtherAsset < ApplicationRecord - include Accountable -end diff --git a/app/models/account/other_liability.rb b/app/models/account/other_liability.rb deleted file mode 100644 index 2467c08d..00000000 --- a/app/models/account/other_liability.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Account::OtherLiability < ApplicationRecord - include Accountable -end diff --git a/app/models/account/property.rb b/app/models/account/property.rb deleted file mode 100644 index 0088dfcd..00000000 --- a/app/models/account/property.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Account::Property < ApplicationRecord - include Accountable -end diff --git a/app/models/account/vehicle.rb b/app/models/account/vehicle.rb deleted file mode 100644 index fd640f2a..00000000 --- a/app/models/account/vehicle.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Account::Vehicle < ApplicationRecord - include Accountable -end diff --git a/app/models/concerns/accountable.rb b/app/models/concerns/accountable.rb index 49120637..916e6cfd 100644 --- a/app/models/concerns/accountable.rb +++ b/app/models/concerns/accountable.rb @@ -1,28 +1,19 @@ module Accountable extend ActiveSupport::Concern - ASSET_TYPES = %w[ Account::Depository Account::Investment Account::Crypto Account::OtherAsset Account::Property Account::Vehicle ] - LIABILITY_TYPES = %w[ Account::Credit Account::Loan Account::OtherLiability ] + ASSET_TYPES = %w[ Depository Investment Crypto Property Vehicle OtherAsset ] + LIABILITY_TYPES = %w[ CreditCard Loan OtherLiability ] TYPES = ASSET_TYPES + LIABILITY_TYPES def self.from_type(type) - return nil unless types.include?(type) || TYPES.include?(type) - "Account::#{type.demodulize}".constantize + return nil unless TYPES.include?(type) + type.constantize end def self.by_classification { assets: ASSET_TYPES, liabilities: LIABILITY_TYPES } end - def self.types(classification = nil) - types = classification ? (classification.to_sym == :asset ? ASSET_TYPES : LIABILITY_TYPES) : TYPES - types.map { |type| type.demodulize } - end - - def self.classification(type) - ASSET_TYPES.include?(type) ? :asset : :liability - end - included do has_one :account, as: :accountable, touch: true end diff --git a/app/models/credit_card.rb b/app/models/credit_card.rb new file mode 100644 index 00000000..467c103a --- /dev/null +++ b/app/models/credit_card.rb @@ -0,0 +1,3 @@ +class CreditCard < ApplicationRecord + include Accountable +end diff --git a/app/models/crypto.rb b/app/models/crypto.rb new file mode 100644 index 00000000..5aec6157 --- /dev/null +++ b/app/models/crypto.rb @@ -0,0 +1,3 @@ +class Crypto < ApplicationRecord + include Accountable +end diff --git a/app/models/depository.rb b/app/models/depository.rb new file mode 100644 index 00000000..8ae1924d --- /dev/null +++ b/app/models/depository.rb @@ -0,0 +1,3 @@ +class Depository < ApplicationRecord + include Accountable +end diff --git a/app/models/account/investment.rb b/app/models/investment.rb similarity index 89% rename from app/models/account/investment.rb rename to app/models/investment.rb index abc988af..145a617d 100644 --- a/app/models/account/investment.rb +++ b/app/models/investment.rb @@ -1,4 +1,4 @@ -class Account::Investment < ApplicationRecord +class Investment < ApplicationRecord include Accountable SUBTYPES = [ diff --git a/app/models/loan.rb b/app/models/loan.rb new file mode 100644 index 00000000..80454a15 --- /dev/null +++ b/app/models/loan.rb @@ -0,0 +1,3 @@ +class Loan < ApplicationRecord + include Accountable +end diff --git a/app/models/other_asset.rb b/app/models/other_asset.rb new file mode 100644 index 00000000..d9434f6b --- /dev/null +++ b/app/models/other_asset.rb @@ -0,0 +1,3 @@ +class OtherAsset < ApplicationRecord + include Accountable +end diff --git a/app/models/other_liability.rb b/app/models/other_liability.rb new file mode 100644 index 00000000..83be97f5 --- /dev/null +++ b/app/models/other_liability.rb @@ -0,0 +1,3 @@ +class OtherLiability < ApplicationRecord + include Accountable +end diff --git a/app/models/property.rb b/app/models/property.rb new file mode 100644 index 00000000..cae953c9 --- /dev/null +++ b/app/models/property.rb @@ -0,0 +1,3 @@ +class Property < ApplicationRecord + include Accountable +end diff --git a/app/models/vehicle.rb b/app/models/vehicle.rb new file mode 100644 index 00000000..13d20150 --- /dev/null +++ b/app/models/vehicle.rb @@ -0,0 +1,3 @@ +class Vehicle < ApplicationRecord + include Accountable +end diff --git a/app/views/accounts/account/_credit.html.erb b/app/views/accounts/account/_credit_card.html.erb similarity index 100% rename from app/views/accounts/account/_credit.html.erb rename to app/views/accounts/account/_credit_card.html.erb diff --git a/app/views/accounts/account/_investment.html.erb b/app/views/accounts/account/_investment.html.erb index d770f824..d403d991 100644 --- a/app/views/accounts/account/_investment.html.erb +++ b/app/views/accounts/account/_investment.html.erb @@ -1 +1 @@ -<%= f.select :subtype, options_for_select(Account::Investment::SUBTYPES, selected: ""), { label: true } %> +<%= f.select :subtype, options_for_select(Investment::SUBTYPES, selected: ""), { label: true } %> diff --git a/app/views/accounts/new.html.erb b/app/views/accounts/new.html.erb index 4bfd6c21..6bb0430e 100644 --- a/app/views/accounts/new.html.erb +++ b/app/views/accounts/new.html.erb @@ -8,14 +8,15 @@
- <%= render "account_type", type: Account::Depository.new, bg_color: "bg-blue-50", text_color: "text-blue-500", icon: "landmark" %> - <%= render "account_type", type: Account::Investment.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "line-chart" %> - <%= render "account_type", type: Account::Property.new, bg_color: "bg-pink-50", text_color: "text-pink-500", icon: "home" %> - <%= render "account_type", type: Account::Vehicle.new, bg_color: "bg-indigo-50", text_color: "text-indigo-500", icon: "car-front" %> - <%= render "account_type", type: Account::Credit.new, bg_color: "bg-violet-50", text_color: "text-violet-500", icon: "credit-card" %> - <%= render "account_type", type: Account::Loan.new, bg_color: "bg-yellow-50", text_color: "text-yellow-500", icon: "hand-coins" %> - <%= render "account_type", type: Account::OtherAsset.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "plus" %> - <%= render "account_type", type: Account::OtherLiability.new, bg_color: "bg-red-50", text_color: "text-red-500", icon: "minus" %> + <%= render "account_type", type: Depository.new, bg_color: "bg-blue-50", text_color: "text-blue-500", icon: "landmark" %> + <%= render "account_type", type: Investment.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "line-chart" %> + <%= render "account_type", type: Crypto.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "bitcoin" %> + <%= render "account_type", type: Property.new, bg_color: "bg-pink-50", text_color: "text-pink-500", icon: "home" %> + <%= render "account_type", type: Vehicle.new, bg_color: "bg-indigo-50", text_color: "text-indigo-500", icon: "car-front" %> + <%= render "account_type", type: CreditCard.new, bg_color: "bg-violet-50", text_color: "text-violet-500", icon: "credit-card" %> + <%= render "account_type", type: Loan.new, bg_color: "bg-yellow-50", text_color: "text-yellow-500", icon: "hand-coins" %> + <%= render "account_type", type: OtherAsset.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "plus" %> + <%= render "account_type", type: OtherLiability.new, bg_color: "bg-red-50", text_color: "text-red-500", icon: "minus" %>
@@ -77,7 +78,7 @@ <%= f.hidden_field :accountable_type %> <%= f.text_field :name, placeholder: t(".name.placeholder"), required: "required", label: t(".name.label"), autofocus: true %> <%= f.collection_select :institution_id, Current.family.institutions.alphabetically, :id, :name, { include_blank: t(".ungrouped"), label: t(".institution") } %> - <%= render "accounts/#{permitted_accountable_partial(@account.accountable_type)}", f: f %> + <%= render "accounts/account/#{permitted_accountable_partial(@account.accountable_type)}", f: f %> <%= f.money_field :balance_money, label: t(".balance"), required: "required" %>
diff --git a/app/views/layouts/_sidebar.html.erb b/app/views/layouts/_sidebar.html.erb index 3afab0f4..6103ca0e 100644 --- a/app/views/layouts/_sidebar.html.erb +++ b/app/views/layouts/_sidebar.html.erb @@ -95,7 +95,7 @@ <%= render partial: "shared/period_select", locals: { button_class: "flex items-center gap-1 w-full cursor-pointer font-bold tracking-wide" } %> <% end %>
- <%= link_to new_account_path, class: "block hover:bg-gray-100 p-2 text-sm font-semibold text-gray-900 flex items-center rounded", title: t(".new_account"), data: { turbo_frame: "modal" } do %> + <%= link_to new_account_path, id: "sidebar-new-account", class: "block hover:bg-gray-100 p-2 text-sm font-semibold text-gray-900 flex items-center rounded", title: t(".new_account"), data: { turbo_frame: "modal" } do %> <%= lucide_icon("plus", class: "w-5 h-5 text-gray-500") %> <% end %>
diff --git a/config/routes.rb b/config/routes.rb index b38ddbb6..66ca561e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,10 +68,19 @@ Rails.application.routes.draw do resources :transfers, only: %i[ new create destroy ] resources :accounts, shallow: true do - get :summary, on: :collection - get :list, on: :collection - post :sync, on: :member - resource :logo, only: %i[show], module: :accounts + collection do + get :summary + get :list + end + + member do + post :sync + end + + scope module: :accounts do + resource :logo, only: :show + end + resources :valuations end diff --git a/db/migrate/20240619125949_rename_accountable_tables.rb b/db/migrate/20240619125949_rename_accountable_tables.rb new file mode 100644 index 00000000..4ef8cdd0 --- /dev/null +++ b/db/migrate/20240619125949_rename_accountable_tables.rb @@ -0,0 +1,87 @@ +class RenameAccountableTables < ActiveRecord::Migration[7.2] + def change + rename_table :account_depositories, :depositories + rename_table :account_investments, :investments + rename_table :account_credits, :credit_cards + rename_table :account_properties, :properties + rename_table :account_vehicles, :vehicles + rename_table :account_loans, :loans + rename_table :account_cryptos, :cryptos + rename_table :account_other_assets, :other_assets + rename_table :account_other_liabilities, :other_liabilities + + reversible do |dir| + dir.up do + update_accountable_types( + 'Account::Depository' => 'Depository', + 'Account::Investment' => 'Investment', + 'Account::Credit' => 'CreditCard', + 'Account::Property' => 'Property', + 'Account::Vehicle' => 'Vehicle', + 'Account::Loan' => 'Loan', + 'Account::Crypto' => 'Crypto', + 'Account::OtherAsset' => 'OtherAsset', + 'Account::OtherLiability' => 'OtherLiability' + ) + + remove_column :accounts, :classification, :virtual + + change_table :accounts do |t| + t.virtual( + :classification, + type: :string, + stored: true, + as: <<-SQL + CASE + WHEN accountable_type IN ('Loan', 'CreditCard', 'OtherLiability') + THEN 'liability' + ELSE 'asset' + END + SQL + ) + end + end + + dir.down do + update_accountable_types( + 'Depository' => 'Account::Depository', + 'Investment' => 'Account::Investment', + 'CreditCard' => 'Account::Credit', + 'Property' => 'Account::Property', + 'Vehicle' => 'Account::Vehicle', + 'Loan' => 'Account::Loan', + 'Crypto' => 'Account::Crypto', + 'OtherAsset' => 'Account::OtherAsset', + 'OtherLiability' => 'Account::OtherLiability' + ) + + remove_column :accounts, :classification, :virtual + + change_table :accounts do |t| + t.virtual( + :classification, + type: :string, + stored: true, + as: <<-SQL + CASE + WHEN accountable_type IN ('Account::Loan', 'Account::Credit', 'Account::OtherLiability') + THEN 'liability' + ELSE 'asset' + END + SQL + ) + end + end + end + end + + private + + def update_accountable_types(mapping) + Account.reset_column_information + + mapping.each do |old_type, new_type| + Account.where(accountable_type: old_type).update_all(accountable_type: new_type) + end + end +end diff --git a/db/schema.rb b/db/schema.rb index be01a8cc..0f06cf85 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: 2024_06_14_121110) do +ActiveRecord::Schema[7.2].define(version: 2024_06_19_125949) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -32,51 +32,6 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_14_121110) do t.index ["account_id"], name: "index_account_balances_on_account_id" end - create_table "account_credits", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "account_cryptos", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "account_depositories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "account_investments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "account_loans", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "account_other_assets", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "account_other_liabilities", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "account_properties", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "account_vehicles", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - create_table "accounts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "subtype" t.uuid "family_id", null: false @@ -87,13 +42,13 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_14_121110) do t.uuid "accountable_id" t.decimal "balance", precision: 19, scale: 4, default: "0.0" t.string "currency", default: "USD" - t.virtual "classification", type: :string, as: "\nCASE\n WHEN ((accountable_type)::text = ANY ((ARRAY['Account::Loan'::character varying, 'Account::Credit'::character varying, 'Account::OtherLiability'::character varying])::text[])) THEN 'liability'::text\n ELSE 'asset'::text\nEND", stored: true t.boolean "is_active", default: true, null: false t.enum "status", default: "ok", null: false, enum_type: "account_status" t.jsonb "sync_warnings", default: [], null: false t.jsonb "sync_errors", default: [], null: false t.date "last_sync_date" t.uuid "institution_id" + t.virtual "classification", type: :string, as: "\nCASE\n WHEN ((accountable_type)::text = ANY ((ARRAY['Loan'::character varying, 'CreditCard'::character varying, 'OtherLiability'::character varying])::text[])) THEN 'liability'::text\n ELSE 'asset'::text\nEND", stored: true t.index ["accountable_type"], name: "index_accounts_on_accountable_type" t.index ["family_id"], name: "index_accounts_on_family_id" t.index ["institution_id"], name: "index_accounts_on_institution_id" @@ -127,6 +82,21 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_14_121110) do t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true end + create_table "credit_cards", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "cryptos", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "depositories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "exchange_rates", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "base_currency", null: false t.string "converted_currency", null: false @@ -245,6 +215,11 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_14_121110) do t.index ["family_id"], name: "index_institutions_on_family_id" end + create_table "investments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "invite_codes", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "token", null: false t.datetime "created_at", null: false @@ -252,6 +227,26 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_14_121110) do t.index ["token"], name: "index_invite_codes_on_token", unique: true end + create_table "loans", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "other_assets", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "other_liabilities", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "properties", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "settings", force: :cascade do |t| t.string "var", null: false t.text "value" @@ -351,6 +346,11 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_14_121110) do t.index ["account_id"], name: "index_valuations_on_account_id" end + create_table "vehicles", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + add_foreign_key "account_balances", "accounts", on_delete: :cascade add_foreign_key "accounts", "families" add_foreign_key "accounts", "institutions" diff --git a/lib/tasks/demo_data.rake b/lib/tasks/demo_data.rake index e5d97cf5..9893df87 100644 --- a/lib/tasks/demo_data.rake +++ b/lib/tasks/demo_data.rake @@ -60,22 +60,22 @@ namespace :demo_data do puts "Loaded mock exchange rates for last 60 days" # ========== Accounts ================ - empty_account = Account.create(name: "Demo Empty Account", family: family, accountable: Account::Depository.new, balance: 500, currency: "USD") - multi_currency_checking = Account.create(name: "Demo Multi-Currency Checking", family: family, accountable: Account::Depository.new, balance: 4000, currency: "EUR") - checking = Account.create(name: "Demo Checking", family: family, accountable: Account::Depository.new, balance: 5000, currency: "USD") - savings = Account.create(name: "Demo Savings", family: family, accountable: Account::Depository.new, balance: 20000, currency: "USD") - credit_card = Account.create(name: "Demo Credit Card", family: family, accountable: Account::Credit.new, balance: 1500, currency: "USD") - retirement = Account.create(name: "Demo 401k", family: family, accountable: Account::Investment.new, balance: 100000, currency: "USD") - euro_savings = Account.create(name: "Demo Euro Savings", family: family, accountable: Account::Depository.new, balance: 10000, currency: "EUR") - brokerage = Account.create(name: "Demo Brokerage Account", family: family, accountable: Account::Investment.new, balance: 10000, currency: "USD") - crypto = Account.create(name: "Bitcoin Account", family: family, accountable: Account::Crypto.new, balance: 0.1, currency: "BTC") - mortgage = Account.create(name: "Demo Mortgage", family: family, accountable: Account::Loan.new, balance: 450000, currency: "USD") - main_car = Account.create(name: "Demo Main Car", family: family, accountable: Account::Vehicle.new, balance: 25000, currency: "USD") - cash = Account.create(name: "Demo Physical Cash", family: family, accountable: Account::OtherAsset.new, balance: 500, currency: "USD") - car_loan = Account.create(name: "Demo Car Loan", family: family, accountable: Account::Loan.new, balance: 10000, currency: "USD") - house = Account.create(name: "Demo Primary Residence", family: family, accountable: Account::Property.new, balance: 2500000, currency: "USD") - personal_iou = Account.create(name: "Demo Personal IOU", family: family, accountable: Account::OtherLiability.new, balance: 1000, currency: "USD") - second_car = Account.create(name: "Demo Secondary Car", family: family, accountable: Account::Vehicle.new, balance: 12000, currency: "USD") + empty_account = Account.create(name: "Demo Empty Account", family: family, accountable: Depository.new, balance: 500, currency: "USD") + multi_currency_checking = Account.create(name: "Demo Multi-Currency Checking", family: family, accountable: Depository.new, balance: 4000, currency: "EUR") + checking = Account.create(name: "Demo Checking", family: family, accountable: Depository.new, balance: 5000, currency: "USD") + savings = Account.create(name: "Demo Savings", family: family, accountable: Depository.new, balance: 20000, currency: "USD") + credit_card = Account.create(name: "Demo Credit Card", family: family, accountable: CreditCard.new, balance: 1500, currency: "USD") + retirement = Account.create(name: "Demo 401k", family: family, accountable: Investment.new, balance: 100000, currency: "USD") + euro_savings = Account.create(name: "Demo Euro Savings", family: family, accountable: Depository.new, balance: 10000, currency: "EUR") + brokerage = Account.create(name: "Demo Brokerage Account", family: family, accountable: Investment.new, balance: 10000, currency: "USD") + crypto = Account.create(name: "Bitcoin Account", family: family, accountable: Crypto.new, balance: 0.1, currency: "BTC") + mortgage = Account.create(name: "Demo Mortgage", family: family, accountable: Loan.new, balance: 450000, currency: "USD") + main_car = Account.create(name: "Demo Main Car", family: family, accountable: Vehicle.new, balance: 25000, currency: "USD") + cash = Account.create(name: "Demo Physical Cash", family: family, accountable: OtherAsset.new, balance: 500, currency: "USD") + car_loan = Account.create(name: "Demo Car Loan", family: family, accountable: Loan.new, balance: 10000, currency: "USD") + house = Account.create(name: "Demo Primary Residence", family: family, accountable: Property.new, balance: 2500000, currency: "USD") + personal_iou = Account.create(name: "Demo Personal IOU", family: family, accountable: OtherLiability.new, balance: 1000, currency: "USD") + second_car = Account.create(name: "Demo Secondary Car", family: family, accountable: Vehicle.new, balance: 12000, currency: "USD") # ========== Transactions ================ diff --git a/test/controllers/accounts_controller_test.rb b/test/controllers/accounts_controller_test.rb index a2ceb6ba..d2393f25 100644 --- a/test/controllers/accounts_controller_test.rb +++ b/test/controllers/accounts_controller_test.rb @@ -47,7 +47,7 @@ class AccountsControllerTest < ActionDispatch::IntegrationTest assert_difference [ "Account.count", "Valuation.count" ], 1 do post accounts_path, params: { account: { - accountable_type: "Account::Depository", + accountable_type: "Depository", balance: 200, subtype: "checking", institution_id: institutions(:chase).id @@ -63,7 +63,7 @@ class AccountsControllerTest < ActionDispatch::IntegrationTest assert_difference -> { Account.count } => 1, -> { Valuation.count } => 2 do post accounts_path, params: { account: { - accountable_type: "Account::Depository", + accountable_type: "Depository", balance: 200, subtype: "checking", institution_id: institutions(:chase).id, diff --git a/test/fixtures/accounts.yml b/test/fixtures/accounts.yml index bbb96c0f..977a919e 100644 --- a/test/fixtures/accounts.yml +++ b/test/fixtures/accounts.yml @@ -2,21 +2,21 @@ collectable: family: dylan_family name: Collectable Account balance: 550 - accountable_type: Account::OtherAsset + accountable_type: OtherAsset accountable: other_asset_collectable iou: family: dylan_family name: IOU (personal debt to friend) balance: 200 - accountable_type: Account::OtherLiability + accountable_type: OtherLiability accountable: other_liability_iou checking: family: dylan_family name: Checking Account balance: 5000 - accountable_type: Account::Depository + accountable_type: Depository accountable: depository_checking institution: chase @@ -24,7 +24,7 @@ savings: family: dylan_family name: Savings account with valuation overrides balance: 19700 - accountable_type: Account::Depository + accountable_type: Depository accountable: depository_savings institution: chase @@ -32,7 +32,7 @@ credit_card: family: dylan_family name: Credit Card balance: 1000 - accountable_type: Account::Credit + accountable_type: CreditCard accountable: credit_one institution: chase @@ -41,7 +41,7 @@ eur_checking: name: Euro Checking Account currency: EUR balance: 12000 - accountable_type: Account::Depository + accountable_type: Depository accountable: depository_eur_checking institution: revolut @@ -51,7 +51,7 @@ multi_currency: name: Multi Currency Account currency: USD # multi-currency accounts still have a "primary" currency balance: 9467 - accountable_type: Account::Depository + accountable_type: Depository accountable: depository_multi_currency institution: revolut @@ -60,7 +60,7 @@ brokerage: name: Robinhood Brokerage Account currency: USD balance: 10000 - accountable_type: Account::Investment + accountable_type: Investment accountable: investment_brokerage mortgage_loan: @@ -68,7 +68,7 @@ mortgage_loan: name: Mortgage Loan currency: USD balance: 500000 - accountable_type: Account::Loan + accountable_type: Loan accountable: loan_mortgage house: @@ -76,7 +76,7 @@ house: name: 123 Maybe Court currency: USD balance: 550000 - accountable_type: Account::Property + accountable_type: Property accountable: property_house car: @@ -84,5 +84,5 @@ car: name: Honda Accord currency: USD balance: 18000 - accountable_type: Account::Vehicle + accountable_type: Vehicle accountable: vehicle_honda_accord diff --git a/test/fixtures/account/credits.yml b/test/fixtures/credit_cards.yml similarity index 100% rename from test/fixtures/account/credits.yml rename to test/fixtures/credit_cards.yml diff --git a/test/fixtures/account/cryptos.yml b/test/fixtures/cryptos.yml similarity index 100% rename from test/fixtures/account/cryptos.yml rename to test/fixtures/cryptos.yml diff --git a/test/fixtures/account/depositories.yml b/test/fixtures/depositories.yml similarity index 100% rename from test/fixtures/account/depositories.yml rename to test/fixtures/depositories.yml diff --git a/test/fixtures/account/investments.yml b/test/fixtures/investments.yml similarity index 100% rename from test/fixtures/account/investments.yml rename to test/fixtures/investments.yml diff --git a/test/fixtures/account/loans.yml b/test/fixtures/loans.yml similarity index 100% rename from test/fixtures/account/loans.yml rename to test/fixtures/loans.yml diff --git a/test/fixtures/account/other_assets.yml b/test/fixtures/other_assets.yml similarity index 100% rename from test/fixtures/account/other_assets.yml rename to test/fixtures/other_assets.yml diff --git a/test/fixtures/account/other_liabilities.yml b/test/fixtures/other_liabilities.yml similarity index 100% rename from test/fixtures/account/other_liabilities.yml rename to test/fixtures/other_liabilities.yml diff --git a/test/fixtures/account/properties.yml b/test/fixtures/properties.yml similarity index 100% rename from test/fixtures/account/properties.yml rename to test/fixtures/properties.yml diff --git a/test/fixtures/account/vehicles.yml b/test/fixtures/vehicles.yml similarity index 100% rename from test/fixtures/account/vehicles.yml rename to test/fixtures/vehicles.yml diff --git a/test/models/account/depository_test.rb b/test/models/account/depository_test.rb deleted file mode 100644 index d93cf1cd..00000000 --- a/test/models/account/depository_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "test_helper" - -class Account::DepositoryTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/test/models/account/investment_test.rb b/test/models/account/investment_test.rb deleted file mode 100644 index 1ed2b6ba..00000000 --- a/test/models/account/investment_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "test_helper" - -class Account::InvestmentTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/test/models/account/other_asset_test.rb b/test/models/account/other_asset_test.rb deleted file mode 100644 index d65911f5..00000000 --- a/test/models/account/other_asset_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "test_helper" - -class Account::OtherAssetTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/test/models/account/other_liability_test.rb b/test/models/account/other_liability_test.rb deleted file mode 100644 index 4c682491..00000000 --- a/test/models/account/other_liability_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "test_helper" - -class Account::OtherLiabilityTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/test/models/account/property_test.rb b/test/models/account/property_test.rb deleted file mode 100644 index 34f6fb71..00000000 --- a/test/models/account/property_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "test_helper" - -class Account::PropertyTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/test/models/account_test.rb b/test/models/account_test.rb index f0894354..10397231 100644 --- a/test/models/account_test.rb +++ b/test/models/account_test.rb @@ -60,15 +60,15 @@ class AccountTest < ActiveSupport::TestCase assert_equal @family.assets, assets.sum assert_equal @family.liabilities, liabilities.sum - depositories = assets.children.find { |group| group.name == "Account::Depository" } - properties = assets.children.find { |group| group.name == "Account::Property" } - vehicles = assets.children.find { |group| group.name == "Account::Vehicle" } - investments = assets.children.find { |group| group.name == "Account::Investment" } - other_assets = assets.children.find { |group| group.name == "Account::OtherAsset" } + depositories = assets.children.find { |group| group.name == "Depository" } + properties = assets.children.find { |group| group.name == "Property" } + vehicles = assets.children.find { |group| group.name == "Vehicle" } + investments = assets.children.find { |group| group.name == "Investment" } + other_assets = assets.children.find { |group| group.name == "OtherAsset" } - credits = liabilities.children.find { |group| group.name == "Account::Credit" } - loans = liabilities.children.find { |group| group.name == "Account::Loan" } - other_liabilities = liabilities.children.find { |group| group.name == "Account::OtherLiability" } + credits = liabilities.children.find { |group| group.name == "CreditCard" } + loans = liabilities.children.find { |group| group.name == "Loan" } + other_liabilities = liabilities.children.find { |group| group.name == "OtherLiability" } assert_equal 4, depositories.children.count assert_equal 1, properties.children.count diff --git a/test/models/account/credit_test.rb b/test/models/credit_card_test.rb similarity index 59% rename from test/models/account/credit_test.rb rename to test/models/credit_card_test.rb index 1c8fd636..8bb8d96e 100644 --- a/test/models/account/credit_test.rb +++ b/test/models/credit_card_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Account::CreditTest < ActiveSupport::TestCase +class CreditCardTest < ActiveSupport::TestCase # test "the truth" do # assert true # end diff --git a/test/models/account/crypto_test.rb b/test/models/crypto_test.rb similarity index 59% rename from test/models/account/crypto_test.rb rename to test/models/crypto_test.rb index 82745f32..095e9474 100644 --- a/test/models/account/crypto_test.rb +++ b/test/models/crypto_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Account::CryptoTest < ActiveSupport::TestCase +class CryptoTest < ActiveSupport::TestCase # test "the truth" do # assert true # end diff --git a/test/models/depository_test.rb b/test/models/depository_test.rb new file mode 100644 index 00000000..9d95638e --- /dev/null +++ b/test/models/depository_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class DepositoryTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/investment_test.rb b/test/models/investment_test.rb new file mode 100644 index 00000000..8d5ffccf --- /dev/null +++ b/test/models/investment_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class InvestmentTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/account/loan_test.rb b/test/models/loan_test.rb similarity index 60% rename from test/models/account/loan_test.rb rename to test/models/loan_test.rb index e793470a..1d60eb6c 100644 --- a/test/models/account/loan_test.rb +++ b/test/models/loan_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Account::LoanTest < ActiveSupport::TestCase +class LoanTest < ActiveSupport::TestCase # test "the truth" do # assert true # end diff --git a/test/models/other_asset_test.rb b/test/models/other_asset_test.rb new file mode 100644 index 00000000..f43ed087 --- /dev/null +++ b/test/models/other_asset_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class OtherAssetTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/other_liability_test.rb b/test/models/other_liability_test.rb new file mode 100644 index 00000000..f92ea5ce --- /dev/null +++ b/test/models/other_liability_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class OtherLiabilityTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/property_test.rb b/test/models/property_test.rb new file mode 100644 index 00000000..caf57b12 --- /dev/null +++ b/test/models/property_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class PropertyTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/account/vehicle_test.rb b/test/models/vehicle_test.rb similarity index 59% rename from test/models/account/vehicle_test.rb rename to test/models/vehicle_test.rb index 011d99f5..71c13e12 100644 --- a/test/models/account/vehicle_test.rb +++ b/test/models/vehicle_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Account::VehicleTest < ActiveSupport::TestCase +class VehicleTest < ActiveSupport::TestCase # test "the truth" do # assert true # end diff --git a/test/system/accounts_test.rb b/test/system/accounts_test.rb new file mode 100644 index 00000000..e93f9658 --- /dev/null +++ b/test/system/accounts_test.rb @@ -0,0 +1,77 @@ +require "application_system_test_case" + +class AccountsTest < ApplicationSystemTestCase + setup do + sign_in @user = users(:family_admin) + + visit root_url + open_new_account_modal + end + + test "can create depository account" do + assert_account_created("Depository") + end + + test "can create investment account" do + assert_account_created("Investment") + end + + test "can create crypto account" do + assert_account_created("Crypto") + end + + test "can create property account" do + assert_account_created("Property") + end + + test "can create vehicle account" do + assert_account_created("Vehicle") + end + + test "can create other asset account" do + assert_account_created("OtherAsset") + end + + test "can create credit card account" do + assert_account_created("CreditCard") + end + + test "can create loan account" do + assert_account_created("Loan") + end + + test "can create other liability account" do + assert_account_created("OtherLiability") + end + + private + + def open_new_account_modal + click_link "sidebar-new-account" + end + + def assert_account_created(accountable_type) + click_link humanized_accountable(accountable_type) + click_link "Enter account balance manually" + + account_name = "[system test] #{accountable_type} Account" + + fill_in "Account name", with: account_name + select "Chase", from: "Financial institution" + fill_in "account[balance]", with: 100.99 + check "Add a start balance for this account" + fill_in "Start date (optional)", with: 10.days.ago.to_date.to_s + fill_in "Start balance (optional)", with: 95 + click_button "Add #{humanized_accountable(accountable_type).downcase}" + + find("details", text: humanized_accountable(accountable_type)).click + assert_text account_name + + visit accounts_url + assert_text account_name + end + + def humanized_accountable(accountable_type) + accountable_type.constantize.model_name.human + end +end