diff --git a/app/controllers/accounts/logos_controller.rb b/app/controllers/account/logos_controller.rb similarity index 74% rename from app/controllers/accounts/logos_controller.rb rename to app/controllers/account/logos_controller.rb index 8e8c50927b6..dd56e6656e3 100644 --- a/app/controllers/accounts/logos_controller.rb +++ b/app/controllers/account/logos_controller.rb @@ -1,4 +1,4 @@ -class Accounts::LogosController < ApplicationController +class Account::LogosController < ApplicationController def show @account = Current.family.accounts.find(params[:account_id]) render_placeholder diff --git a/app/controllers/transfers_controller.rb b/app/controllers/account/transfers_controller.rb similarity index 59% rename from app/controllers/transfers_controller.rb rename to app/controllers/account/transfers_controller.rb index 6e231a88940..13a7ea8bfad 100644 --- a/app/controllers/transfers_controller.rb +++ b/app/controllers/account/transfers_controller.rb @@ -1,17 +1,17 @@ -class TransfersController < ApplicationController +class Account::TransfersController < ApplicationController layout "with_sidebar" before_action :set_transfer, only: :destroy def new - @transfer = Transfer.new + @transfer = Account::Transfer.new end def create from_account = Current.family.accounts.find(transfer_params[:from_account_id]) to_account = Current.family.accounts.find(transfer_params[:to_account_id]) - @transfer = Transfer.build_from_accounts from_account, to_account, \ + @transfer = Account::Transfer.build_from_accounts from_account, to_account, \ date: transfer_params[:date], amount: transfer_params[:amount].to_d, currency: transfer_params[:currency], @@ -20,7 +20,10 @@ def create if @transfer.save redirect_to transactions_path, notice: t(".success") else - render :new, status: :unprocessable_entity + # TODO: this is not an ideal way to handle errors and should eventually be improved. + # See: https://github.com/hotwired/turbo-rails/pull/367 + flash[:error] = @transfer.errors.full_messages.to_sentence + redirect_to transactions_path end end @@ -32,10 +35,10 @@ def destroy private def set_transfer - @transfer = Transfer.find(params[:id]) + @transfer = Account::Transfer.find(params[:id]) end def transfer_params - params.require(:transfer).permit(:from_account_id, :to_account_id, :amount, :currency, :date, :name) + params.require(:account_transfer).permit(:from_account_id, :to_account_id, :amount, :currency, :date, :name) end end diff --git a/app/controllers/categories/deletions_controller.rb b/app/controllers/category/deletions_controller.rb similarity index 90% rename from app/controllers/categories/deletions_controller.rb rename to app/controllers/category/deletions_controller.rb index 678823f21f5..96ff4c47ff7 100644 --- a/app/controllers/categories/deletions_controller.rb +++ b/app/controllers/category/deletions_controller.rb @@ -1,4 +1,4 @@ -class Categories::DeletionsController < ApplicationController +class Category::DeletionsController < ApplicationController layout "with_sidebar" before_action :set_category diff --git a/app/controllers/categories/dropdowns_controller.rb b/app/controllers/category/dropdowns_controller.rb similarity index 88% rename from app/controllers/categories/dropdowns_controller.rb rename to app/controllers/category/dropdowns_controller.rb index 3da1bfe6aee..ef2322e41ba 100644 --- a/app/controllers/categories/dropdowns_controller.rb +++ b/app/controllers/category/dropdowns_controller.rb @@ -1,4 +1,4 @@ -class Categories::DropdownsController < ApplicationController +class Category::DropdownsController < ApplicationController before_action :set_from_params def show diff --git a/app/controllers/tags/deletions_controller.rb b/app/controllers/tag/deletions_controller.rb similarity index 89% rename from app/controllers/tags/deletions_controller.rb rename to app/controllers/tag/deletions_controller.rb index 8916ce74a7c..19183c5711c 100644 --- a/app/controllers/tags/deletions_controller.rb +++ b/app/controllers/tag/deletions_controller.rb @@ -1,4 +1,4 @@ -class Tags::DeletionsController < ApplicationController +class Tag::DeletionsController < ApplicationController layout "with_sidebar" before_action :set_tag diff --git a/app/controllers/transactions/rows_controller.rb b/app/controllers/transaction/rows_controller.rb similarity index 87% rename from app/controllers/transactions/rows_controller.rb rename to app/controllers/transaction/rows_controller.rb index 159e75a9c78..08f081b92c6 100644 --- a/app/controllers/transactions/rows_controller.rb +++ b/app/controllers/transaction/rows_controller.rb @@ -1,4 +1,4 @@ -class Transactions::RowsController < ApplicationController +class Transaction::RowsController < ApplicationController before_action :set_transaction, only: %i[ show update ] def show diff --git a/app/controllers/transaction/rules_controller.rb b/app/controllers/transaction/rules_controller.rb new file mode 100644 index 00000000000..7c7b157a4ba --- /dev/null +++ b/app/controllers/transaction/rules_controller.rb @@ -0,0 +1,6 @@ +class Transaction::RulesController < ApplicationController + layout "with_sidebar" + + def index + end +end diff --git a/app/controllers/transactions/rules_controller.rb b/app/controllers/transactions/rules_controller.rb deleted file mode 100644 index 3c1db811a99..00000000000 --- a/app/controllers/transactions/rules_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Transactions::RulesController < ApplicationController - layout "with_sidebar" - - def index - end -end diff --git a/app/models/transfer.rb b/app/models/account/transfer.rb similarity index 97% rename from app/models/transfer.rb rename to app/models/account/transfer.rb index bb3778fb09d..9a3aeb4cb00 100644 --- a/app/models/transfer.rb +++ b/app/models/account/transfer.rb @@ -1,4 +1,4 @@ -class Transfer < ApplicationRecord +class Account::Transfer < ApplicationRecord has_many :transactions, dependent: :nullify validate :transaction_count, :from_different_accounts, :net_zero_flows, :all_transactions_marked diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 1657873afe3..bad2aaf6268 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -4,7 +4,7 @@ class Transaction < ApplicationRecord monetize :amount belongs_to :account - belongs_to :transfer, optional: true + belongs_to :transfer, optional: true, class_name: "Account::Transfer" belongs_to :category, optional: true belongs_to :merchant, optional: true has_many :taggings, as: :taggable, dependent: :destroy @@ -70,7 +70,7 @@ def mark_transfers! update_all marked_as_transfer: true # Attempt to "auto match" and save a transfer if 2 transactions selected - Transfer.new(transactions: all).save if all.count == 2 + Account::Transfer.new(transactions: all).save if all.count == 2 end def daily_totals(transactions, period: Period.last_30_days, currency: Current.family.currency) diff --git a/app/views/accounts/logos/show.svg.erb b/app/views/account/logos/show.svg.erb similarity index 100% rename from app/views/accounts/logos/show.svg.erb rename to app/views/account/logos/show.svg.erb diff --git a/app/views/transfers/_form.html.erb b/app/views/account/transfers/_form.html.erb similarity index 96% rename from app/views/transfers/_form.html.erb rename to app/views/account/transfers/_form.html.erb index 0a8cfcd1e2b..e8cdd61eec9 100644 --- a/app/views/transfers/_form.html.erb +++ b/app/views/account/transfers/_form.html.erb @@ -1,4 +1,4 @@ -<%= form_with model: transfer do |f| %> +<%= form_with model: transfer, data: { turbo_frame: "_top" } do |f| %>
<%= link_to new_transaction_path(nature: "expense"), data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-gray-400" do %> diff --git a/app/views/transfers/_transfer.html.erb b/app/views/account/transfers/_transfer.html.erb similarity index 96% rename from app/views/transfers/_transfer.html.erb rename to app/views/account/transfers/_transfer.html.erb index fae63dae851..f0e0c8572f9 100644 --- a/app/views/transfers/_transfer.html.erb +++ b/app/views/account/transfers/_transfer.html.erb @@ -2,7 +2,7 @@
- <%= button_to transfer_path(transfer), + <%= button_to account_transfer_path(transfer), method: :delete, class: "flex items-center group/transfer", data: { diff --git a/app/views/transfers/new.html.erb b/app/views/account/transfers/new.html.erb similarity index 100% rename from app/views/transfers/new.html.erb rename to app/views/account/transfers/new.html.erb diff --git a/app/views/accounts/account/_credit_card.html.erb b/app/views/accounts/accountables/_credit_card.html.erb similarity index 100% rename from app/views/accounts/account/_credit_card.html.erb rename to app/views/accounts/accountables/_credit_card.html.erb diff --git a/app/views/accounts/account/_crypto.html.erb b/app/views/accounts/accountables/_crypto.html.erb similarity index 100% rename from app/views/accounts/account/_crypto.html.erb rename to app/views/accounts/accountables/_crypto.html.erb diff --git a/app/views/accounts/account/_depository.html.erb b/app/views/accounts/accountables/_depository.html.erb similarity index 100% rename from app/views/accounts/account/_depository.html.erb rename to app/views/accounts/accountables/_depository.html.erb diff --git a/app/views/accounts/account/_investment.html.erb b/app/views/accounts/accountables/_investment.html.erb similarity index 100% rename from app/views/accounts/account/_investment.html.erb rename to app/views/accounts/accountables/_investment.html.erb diff --git a/app/views/accounts/account/_loan.html.erb b/app/views/accounts/accountables/_loan.html.erb similarity index 100% rename from app/views/accounts/account/_loan.html.erb rename to app/views/accounts/accountables/_loan.html.erb diff --git a/app/views/accounts/account/_other_asset.html.erb b/app/views/accounts/accountables/_other_asset.html.erb similarity index 100% rename from app/views/accounts/account/_other_asset.html.erb rename to app/views/accounts/accountables/_other_asset.html.erb diff --git a/app/views/accounts/account/_other_liability.html.erb b/app/views/accounts/accountables/_other_liability.html.erb similarity index 100% rename from app/views/accounts/account/_other_liability.html.erb rename to app/views/accounts/accountables/_other_liability.html.erb diff --git a/app/views/accounts/account/_property.html.erb b/app/views/accounts/accountables/_property.html.erb similarity index 100% rename from app/views/accounts/account/_property.html.erb rename to app/views/accounts/accountables/_property.html.erb diff --git a/app/views/accounts/account/_vehicle.html.erb b/app/views/accounts/accountables/_vehicle.html.erb similarity index 100% rename from app/views/accounts/account/_vehicle.html.erb rename to app/views/accounts/accountables/_vehicle.html.erb diff --git a/app/views/accounts/new.html.erb b/app/views/accounts/new.html.erb index 6bb0430ea4e..878cafc06f2 100644 --- a/app/views/accounts/new.html.erb +++ b/app/views/accounts/new.html.erb @@ -78,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/account/#{permitted_accountable_partial(@account.accountable_type)}", f: f %> + <%= render "accounts/accountables/#{permitted_accountable_partial(@account.accountable_type)}", f: f %> <%= f.money_field :balance_money, label: t(".balance"), required: "required" %>
diff --git a/app/views/categories/deletions/new.html.erb b/app/views/category/deletions/new.html.erb similarity index 100% rename from app/views/categories/deletions/new.html.erb rename to app/views/category/deletions/new.html.erb diff --git a/app/views/categories/dropdowns/_row.html.erb b/app/views/category/dropdowns/_row.html.erb similarity index 100% rename from app/views/categories/dropdowns/_row.html.erb rename to app/views/category/dropdowns/_row.html.erb diff --git a/app/views/categories/dropdowns/show.html.erb b/app/views/category/dropdowns/show.html.erb similarity index 96% rename from app/views/categories/dropdowns/show.html.erb rename to app/views/category/dropdowns/show.html.erb index 098e00e80ec..0ddfd1ec91e 100644 --- a/app/views/categories/dropdowns/show.html.erb +++ b/app/views/category/dropdowns/show.html.erb @@ -11,7 +11,7 @@ <%= t(".no_categories") %>
<% @categories.each do |category| %> - <%= render partial: "categories/dropdowns/row", locals: { category: } %> + <%= render partial: "category/dropdowns/row", locals: { category: } %> <% end %>

diff --git a/app/views/tags/deletions/new.html.erb b/app/views/tag/deletions/new.html.erb similarity index 100% rename from app/views/tags/deletions/new.html.erb rename to app/views/tag/deletions/new.html.erb diff --git a/app/views/transactions/rows/show.html.erb b/app/views/transaction/rows/show.html.erb similarity index 100% rename from app/views/transactions/rows/show.html.erb rename to app/views/transaction/rows/show.html.erb diff --git a/app/views/transactions/rules/index.html.erb b/app/views/transaction/rules/index.html.erb similarity index 100% rename from app/views/transactions/rules/index.html.erb rename to app/views/transaction/rules/index.html.erb diff --git a/app/views/transactions/_date_group.html.erb b/app/views/transactions/_date_group.html.erb index 7ec9be4b979..80de9bd99ff 100644 --- a/app/views/transactions/_date_group.html.erb +++ b/app/views/transactions/_date_group.html.erb @@ -1,5 +1,5 @@ <%# locals: (date:, group:) %> -
+
<%= check_box_tag "#{date}_transactions_selection", diff --git a/app/views/transactions/_form.html.erb b/app/views/transactions/_form.html.erb index 4839772e87e..575e9fc6a19 100644 --- a/app/views/transactions/_form.html.erb +++ b/app/views/transactions/_form.html.erb @@ -3,7 +3,7 @@
<%= radio_tab_tag form: f, name: :nature, value: :expense, label: t(".expense"), icon: "minus-circle", checked: params[:nature] == "expense" || params[:nature].nil? %> <%= radio_tab_tag form: f, name: :nature, value: :income, label: t(".income"), icon: "plus-circle", checked: params[:nature] == "income" %> - <%= link_to new_transfer_path, data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-gray-400 group-has-[:checked]:bg-white group-has-[:checked]:text-gray-800 group-has-[:checked]:shadow-sm" do %> + <%= link_to new_account_transfer_path, data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-gray-400 group-has-[:checked]:bg-white group-has-[:checked]:text-gray-800 group-has-[:checked]:shadow-sm" do %> <%= lucide_icon "arrow-right-left", class: "w-5 h-5" %> <%= tag.span t(".transfer") %> <% end %> diff --git a/app/views/transactions/_selection_bar.html.erb b/app/views/transactions/_selection_bar.html.erb index d03ca5f3bb2..3def43bb82e 100644 --- a/app/views/transactions/_selection_bar.html.erb +++ b/app/views/transactions/_selection_bar.html.erb @@ -18,7 +18,7 @@ accept: t(".mark_transfers_confirm"), } } do |f| %> - <% end %> diff --git a/config/locales/views/account/transfers/en.yml b/config/locales/views/account/transfers/en.yml new file mode 100644 index 00000000000..4ae3701ba38 --- /dev/null +++ b/config/locales/views/account/transfers/en.yml @@ -0,0 +1,28 @@ +--- +en: + account: + transfers: + create: + success: Transfer created + destroy: + success: Transfer removed + form: + amount: Amount + date: Date + description: Description + description_placeholder: Transfer from Checking to Savings + expense: Expense + from: From + income: Income + select_account: Select account + submit: Create transfer + to: To + transfer: Transfer + new: + title: New transfer + transfer: + remove_body: This will NOT delete the underlying transactions. It will just + remove the transfer. + remove_confirm: Confirm + remove_title: Remove transfer? + transfer_name: Transfer from %{from_account} to %{to_account} diff --git a/config/locales/views/categories/en.yml b/config/locales/views/categories/en.yml index 9451094a585..3da3ab1e9d5 100644 --- a/config/locales/views/categories/en.yml +++ b/config/locales/views/categories/en.yml @@ -3,27 +3,6 @@ en: categories: create: success: New transaction category created successfully - deletions: - create: - success: Transaction category deleted successfully - new: - category: Category - delete_and_leave_uncategorized: Delete "%{category_name}" and leave uncategorized - delete_and_recategorize: Delete "%{category_name}" and assign new category - delete_category: Delete category? - explanation: By deleting this category, every transaction that has the "%{category_name}" - category will be uncategorized. Instead of leaving them uncategorized, you - can also assign a new category below. - replacement_category_prompt: Select category - dropdowns: - row: - delete: Delete category - edit: Edit category - show: - add_new: Add new - clear: Clear - no_categories: No categories found - search_placeholder: Search edit: edit: Edit category form: diff --git a/config/locales/views/category/deletions/en.yml b/config/locales/views/category/deletions/en.yml new file mode 100644 index 00000000000..3568374ebf9 --- /dev/null +++ b/config/locales/views/category/deletions/en.yml @@ -0,0 +1,15 @@ +--- +en: + category: + deletions: + create: + success: Transaction category deleted successfully + new: + category: Category + delete_and_leave_uncategorized: Delete "%{category_name}" and leave uncategorized + delete_and_recategorize: Delete "%{category_name}" and assign new category + delete_category: Delete category? + explanation: By deleting this category, every transaction that has the "%{category_name}" + category will be uncategorized. Instead of leaving them uncategorized, you + can also assign a new category below. + replacement_category_prompt: Select category diff --git a/config/locales/views/category/dropdowns/en.yml b/config/locales/views/category/dropdowns/en.yml new file mode 100644 index 00000000000..5b9e8248f95 --- /dev/null +++ b/config/locales/views/category/dropdowns/en.yml @@ -0,0 +1,12 @@ +--- +en: + category: + dropdowns: + row: + delete: Delete category + edit: Edit category + show: + add_new: Add new + clear: Clear + no_categories: No categories found + search_placeholder: Search diff --git a/config/locales/views/tag/deletions/en.yml b/config/locales/views/tag/deletions/en.yml new file mode 100644 index 00000000000..c69ec8d5d97 --- /dev/null +++ b/config/locales/views/tag/deletions/en.yml @@ -0,0 +1,15 @@ +--- +en: + tag: + deletions: + create: + deleted: Tag deleted + new: + delete_and_leave_uncategorized: Delete "%{tag_name}" + delete_and_recategorize: Delete "%{tag_name}" and assign new tag + delete_tag: Delete tag? + explanation: "%{tag_name} will be removed from transactions and other taggable + entities. Instead of leaving them untagged, you can also assign a new tag + below." + replacement_tag_prompt: Select tag + tag: Tag diff --git a/config/locales/views/tags/en.yml b/config/locales/views/tags/en.yml index 506c41a3a80..a2cc464f725 100644 --- a/config/locales/views/tags/en.yml +++ b/config/locales/views/tags/en.yml @@ -3,18 +3,6 @@ en: tags: create: created: Tag created - deletions: - create: - deleted: Tag deleted - new: - delete_and_leave_uncategorized: Delete "%{tag_name}" - delete_and_recategorize: Delete "%{tag_name}" and assign new tag - delete_tag: Delete tag? - explanation: "%{tag_name} will be removed from transactions and other taggable - entities. Instead of leaving them untagged, you can also assign a new tag - below." - replacement_tag_prompt: Select tag - tag: Tag edit: edit: Edit tag form: diff --git a/config/locales/views/transfers/en.yml b/config/locales/views/transfers/en.yml deleted file mode 100644 index 79b842a2934..00000000000 --- a/config/locales/views/transfers/en.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -en: - transfers: - create: - success: Transfer created - destroy: - success: Transfer removed - form: - amount: Amount - date: Date - description: Description - description_placeholder: Transfer from Checking to Savings - expense: Expense - from: From - income: Income - select_account: Select account - submit: Create transfer - to: To - transfer: Transfer - new: - title: New transfer - transfer: - remove_body: This will NOT delete the underlying transactions. It will just - remove the transfer. - remove_confirm: Confirm - remove_title: Remove transfer? - transfer_name: Transfer from %{from_account} to %{to_account} diff --git a/config/routes.rb b/config/routes.rb index a6026f2e773..2f57f282ada 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -38,18 +38,24 @@ end resources :tags, except: %i[ show destroy ] do - resources :deletions, only: %i[ new create ], module: :tags + resources :deletions, only: %i[ new create ], module: :tag + end + + namespace :category do + resource :dropdown, only: :show end resources :categories do - resources :deletions, only: %i[ new create ], module: :categories - collection do - resource :dropdown, only: :show, module: :categories, as: :category_dropdown - end + resources :deletions, only: %i[ new create ], module: :category end resources :merchants, only: %i[ index new create edit update destroy ] + namespace :transaction do + resources :rows, only: %i[ show update ] + resources :rules, only: %i[ index ] + end + resources :transactions do collection do post "bulk_delete" @@ -57,17 +63,14 @@ post "bulk_update" post "mark_transfers" post "unmark_transfers" - - scope module: :transactions, as: :transaction do - resources :rows, only: %i[ show update ] - resources :rules, only: %i[ index ] - end end end - resources :transfers, only: %i[ new create destroy ] + namespace :account do + resources :transfers, only: %i[ new create destroy ] + end - resources :accounts, shallow: true do + resources :accounts do collection do get :summary get :list @@ -77,11 +80,8 @@ post :sync end - scope module: :accounts do - resource :logo, only: :show - end - - resources :valuations + resource :logo, only: :show, module: :account + resources :valuations, shallow: true end resources :institutions, except: %i[ index show ] diff --git a/db/migrate/20240620125026_rename_transfer_table.rb b/db/migrate/20240620125026_rename_transfer_table.rb new file mode 100644 index 00000000000..20bf619f058 --- /dev/null +++ b/db/migrate/20240620125026_rename_transfer_table.rb @@ -0,0 +1,5 @@ +class RenameTransferTable < ActiveRecord::Migration[7.2] + def change + rename_table :transfers, :account_transfers + end +end diff --git a/db/schema.rb b/db/schema.rb index b82ad3469dd..f0f7d7d9ad6 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_20_122201) do +ActiveRecord::Schema[7.2].define(version: 2024_06_20_125026) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -32,6 +32,11 @@ t.index ["account_id"], name: "index_account_balances_on_account_id" end + create_table "account_transfers", 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 @@ -313,11 +318,6 @@ t.index ["transfer_id"], name: "index_transactions_on_transfer_id" end - create_table "transfers", 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 "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "family_id", null: false t.string "first_name" @@ -362,10 +362,10 @@ add_foreign_key "merchants", "families" add_foreign_key "taggings", "tags" add_foreign_key "tags", "families" + add_foreign_key "transactions", "account_transfers", column: "transfer_id" add_foreign_key "transactions", "accounts", on_delete: :cascade add_foreign_key "transactions", "categories", on_delete: :nullify add_foreign_key "transactions", "merchants" - add_foreign_key "transactions", "transfers" add_foreign_key "users", "families" add_foreign_key "valuations", "accounts", on_delete: :cascade end diff --git a/test/controllers/transfers_controller_test.rb b/test/controllers/account/transfers_controller_test.rb similarity index 53% rename from test/controllers/transfers_controller_test.rb rename to test/controllers/account/transfers_controller_test.rb index 4a139f67fa6..9ceb5a306a5 100644 --- a/test/controllers/transfers_controller_test.rb +++ b/test/controllers/account/transfers_controller_test.rb @@ -1,19 +1,19 @@ require "test_helper" -class TransfersControllerTest < ActionDispatch::IntegrationTest +class Account::TransfersControllerTest < ActionDispatch::IntegrationTest setup do sign_in users(:family_admin) end test "should get new" do - get new_transfer_url + get new_account_transfer_url assert_response :success end test "can create transfers" do - assert_difference "Transfer.count", 1 do - post transfers_url, params: { - transfer: { + assert_difference "Account::Transfer.count", 1 do + post account_transfers_url, params: { + account_transfer: { from_account_id: accounts(:checking).id, to_account_id: accounts(:savings).id, date: Date.current, @@ -26,8 +26,8 @@ class TransfersControllerTest < ActionDispatch::IntegrationTest end test "can destroy transfer" do - assert_difference -> { Transfer.count } => -1, -> { Transaction.count } => 0 do - delete transfer_url(transfers(:credit_card_payment)) + assert_difference -> { Account::Transfer.count } => -1, -> { Transaction.count } => 0 do + delete account_transfer_url(account_transfers(:credit_card_payment)) end end end diff --git a/test/controllers/categories/deletions_controller_test.rb b/test/controllers/category/deletions_controller_test.rb similarity index 93% rename from test/controllers/categories/deletions_controller_test.rb rename to test/controllers/category/deletions_controller_test.rb index a9b0caa8077..c8bd3d37cce 100644 --- a/test/controllers/categories/deletions_controller_test.rb +++ b/test/controllers/category/deletions_controller_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Categories::DeletionsControllerTest < ActionDispatch::IntegrationTest +class Category::DeletionsControllerTest < ActionDispatch::IntegrationTest setup do sign_in users(:family_admin) @category = categories(:food_and_drink) diff --git a/test/controllers/tags/deletions_controller_test.rb b/test/controllers/tag/deletions_controller_test.rb similarity index 93% rename from test/controllers/tags/deletions_controller_test.rb rename to test/controllers/tag/deletions_controller_test.rb index a176f5b593b..57bf6df258f 100644 --- a/test/controllers/tags/deletions_controller_test.rb +++ b/test/controllers/tag/deletions_controller_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Tags::DeletionsControllerTest < ActionDispatch::IntegrationTest +class Tag::DeletionsControllerTest < ActionDispatch::IntegrationTest setup do sign_in @user = users(:family_admin) @user_tags = @user.family.tags diff --git a/test/fixtures/transfers.yml b/test/fixtures/account/transfers.yml similarity index 100% rename from test/fixtures/transfers.yml rename to test/fixtures/account/transfers.yml diff --git a/test/fixtures/accounts.yml b/test/fixtures/accounts.yml index 977a919eacb..25633c4e0da 100644 --- a/test/fixtures/accounts.yml +++ b/test/fixtures/accounts.yml @@ -22,7 +22,7 @@ checking: savings: family: dylan_family - name: Savings account with valuation overrides + name: Savings account balance: 19700 accountable_type: Depository accountable: depository_savings diff --git a/test/models/transfer_test.rb b/test/models/transfer_test.rb index 2d1b26cd7b6..0ca4be918dc 100644 --- a/test/models/transfer_test.rb +++ b/test/models/transfer_test.rb @@ -8,14 +8,14 @@ class TransferTest < ActiveSupport::TestCase end test "transfer valid if it has inflow and outflow from different accounts for the same amount" do - transfer = Transfer.create! transactions: [ @inflow, @outflow ] + transfer = Account::Transfer.create! transactions: [ @inflow, @outflow ] assert transfer.valid? end test "transfer must have 2 transactions" do - invalid_transfer_1 = Transfer.new transactions: [ @outflow ] - invalid_transfer_2 = Transfer.new transactions: [ @inflow, @outflow, transactions(:savings_four) ] + invalid_transfer_1 = Account::Transfer.new transactions: [ @outflow ] + invalid_transfer_2 = Account::Transfer.new transactions: [ @inflow, @outflow, transactions(:savings_four) ] assert invalid_transfer_1.invalid? assert invalid_transfer_2.invalid? @@ -27,7 +27,7 @@ class TransferTest < ActiveSupport::TestCase outflow = account.transactions.create! date: Date.current, name: "Outflow", amount: 100 assert_raise ActiveRecord::RecordInvalid do - Transfer.create! transactions: [ inflow, outflow ] + Account::Transfer.create! transactions: [ inflow, outflow ] end end @@ -35,7 +35,7 @@ class TransferTest < ActiveSupport::TestCase @inflow.update! marked_as_transfer: false assert_raise ActiveRecord::RecordInvalid do - Transfer.create! transactions: [ @inflow, @outflow ] + Account::Transfer.create! transactions: [ @inflow, @outflow ] end end @@ -43,7 +43,7 @@ class TransferTest < ActiveSupport::TestCase @outflow.update! amount: 105 assert_raises ActiveRecord::RecordInvalid do - Transfer.create! transactions: [ @inflow, @outflow ] + Account::Transfer.create! transactions: [ @inflow, @outflow ] end end end diff --git a/test/system/transfers_test.rb b/test/system/transfers_test.rb new file mode 100644 index 00000000000..4f70f101489 --- /dev/null +++ b/test/system/transfers_test.rb @@ -0,0 +1,82 @@ +require "application_system_test_case" + +class TransfersTest < ApplicationSystemTestCase + setup do + sign_in @user = users(:family_admin) + visit transactions_url + end + + test "can create a transfer" do + checking_name = accounts(:checking).name + savings_name = accounts(:savings).name + transfer_date = Date.current + + click_on "New transaction" + + # Will navigate to different route in same modal + click_on "Transfer" + assert_text "New transfer" + + fill_in "Description", with: "Transfer txn name" + select checking_name, from: "From" + select savings_name, from: "To" + fill_in "account_transfer[amount]", with: 500 + fill_in "Date", with: transfer_date + click_button "Create transfer" + + within "#date-group-" + transfer_date.to_s do + transfer_name = "Transfer from #{checking_name} to #{savings_name}" + find("details", text: transfer_name).click + assert_text "Transfer txn name", count: 2 + end + end + + test "can match 2 transactions and create a transfer" do + transfer_date = Date.current + outflow = Transaction.create! name: "Outflow from savings account", date: transfer_date, account: accounts(:savings), amount: 100 + inflow = Transaction.create! name: "Inflow to checking account", date: transfer_date, account: accounts(:checking), amount: -100 + + visit transactions_url + + transaction_checkbox(inflow).check + transaction_checkbox(outflow).check + + bulk_transfer_action_button.click + + click_on "Mark as transfers" + + within "#date-group-" + transfer_date.to_s do + transfer_name = "Transfer from #{outflow.account.name} to #{inflow.account.name}" + find("details", text: transfer_name).click + assert_text inflow.name + assert_text outflow.name + end + end + + test "can mark a single transaction as a transfer" do + txn = @user.family.transactions.ordered.first + + within "#" + dom_id(txn) do + assert_text "Uncategorized" + end + + transaction_checkbox(txn).check + + bulk_transfer_action_button.click + click_on "Mark as transfers" + + within "#" + dom_id(txn) do + assert_no_text "Uncategorized" + end + end + + private + + def transaction_checkbox(transaction) + find("#" + dom_id(transaction, "selection")) + end + + def bulk_transfer_action_button + find("#bulk-transfer-btn") + end +end