mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-22 14:49:38 +02:00
Account namespace updates: part 4 (transfers, singular namespacing) (#896)
* Move Transfer to Account namespace * Fix partial resolution due to namespacing plurality * Make category and tag controllers consistent with namespacing convention * Update stale partial reference
This commit is contained in:
parent
dc3147c101
commit
bddaab0192
50 changed files with 227 additions and 127 deletions
|
@ -1,4 +1,4 @@
|
||||||
class Accounts::LogosController < ApplicationController
|
class Account::LogosController < ApplicationController
|
||||||
def show
|
def show
|
||||||
@account = Current.family.accounts.find(params[:account_id])
|
@account = Current.family.accounts.find(params[:account_id])
|
||||||
render_placeholder
|
render_placeholder
|
|
@ -1,17 +1,17 @@
|
||||||
class TransfersController < ApplicationController
|
class Account::TransfersController < ApplicationController
|
||||||
layout "with_sidebar"
|
layout "with_sidebar"
|
||||||
|
|
||||||
before_action :set_transfer, only: :destroy
|
before_action :set_transfer, only: :destroy
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@transfer = Transfer.new
|
@transfer = Account::Transfer.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
from_account = Current.family.accounts.find(transfer_params[:from_account_id])
|
from_account = Current.family.accounts.find(transfer_params[:from_account_id])
|
||||||
to_account = Current.family.accounts.find(transfer_params[:to_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],
|
date: transfer_params[:date],
|
||||||
amount: transfer_params[:amount].to_d,
|
amount: transfer_params[:amount].to_d,
|
||||||
currency: transfer_params[:currency],
|
currency: transfer_params[:currency],
|
||||||
|
@ -20,7 +20,10 @@ class TransfersController < ApplicationController
|
||||||
if @transfer.save
|
if @transfer.save
|
||||||
redirect_to transactions_path, notice: t(".success")
|
redirect_to transactions_path, notice: t(".success")
|
||||||
else
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,10 +35,10 @@ class TransfersController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_transfer
|
def set_transfer
|
||||||
@transfer = Transfer.find(params[:id])
|
@transfer = Account::Transfer.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def transfer_params
|
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
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
class Categories::DeletionsController < ApplicationController
|
class Category::DeletionsController < ApplicationController
|
||||||
layout "with_sidebar"
|
layout "with_sidebar"
|
||||||
|
|
||||||
before_action :set_category
|
before_action :set_category
|
|
@ -1,4 +1,4 @@
|
||||||
class Categories::DropdownsController < ApplicationController
|
class Category::DropdownsController < ApplicationController
|
||||||
before_action :set_from_params
|
before_action :set_from_params
|
||||||
|
|
||||||
def show
|
def show
|
|
@ -1,4 +1,4 @@
|
||||||
class Tags::DeletionsController < ApplicationController
|
class Tag::DeletionsController < ApplicationController
|
||||||
layout "with_sidebar"
|
layout "with_sidebar"
|
||||||
|
|
||||||
before_action :set_tag
|
before_action :set_tag
|
|
@ -1,4 +1,4 @@
|
||||||
class Transactions::RowsController < ApplicationController
|
class Transaction::RowsController < ApplicationController
|
||||||
before_action :set_transaction, only: %i[ show update ]
|
before_action :set_transaction, only: %i[ show update ]
|
||||||
|
|
||||||
def show
|
def show
|
6
app/controllers/transaction/rules_controller.rb
Normal file
6
app/controllers/transaction/rules_controller.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
class Transaction::RulesController < ApplicationController
|
||||||
|
layout "with_sidebar"
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +0,0 @@
|
||||||
class Transactions::RulesController < ApplicationController
|
|
||||||
layout "with_sidebar"
|
|
||||||
|
|
||||||
def index
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,4 +1,4 @@
|
||||||
class Transfer < ApplicationRecord
|
class Account::Transfer < ApplicationRecord
|
||||||
has_many :transactions, dependent: :nullify
|
has_many :transactions, dependent: :nullify
|
||||||
|
|
||||||
validate :transaction_count, :from_different_accounts, :net_zero_flows, :all_transactions_marked
|
validate :transaction_count, :from_different_accounts, :net_zero_flows, :all_transactions_marked
|
|
@ -4,7 +4,7 @@ class Transaction < ApplicationRecord
|
||||||
monetize :amount
|
monetize :amount
|
||||||
|
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
belongs_to :transfer, optional: true
|
belongs_to :transfer, optional: true, class_name: "Account::Transfer"
|
||||||
belongs_to :category, optional: true
|
belongs_to :category, optional: true
|
||||||
belongs_to :merchant, optional: true
|
belongs_to :merchant, optional: true
|
||||||
has_many :taggings, as: :taggable, dependent: :destroy
|
has_many :taggings, as: :taggable, dependent: :destroy
|
||||||
|
@ -70,7 +70,7 @@ class Transaction < ApplicationRecord
|
||||||
update_all marked_as_transfer: true
|
update_all marked_as_transfer: true
|
||||||
|
|
||||||
# Attempt to "auto match" and save a transfer if 2 transactions selected
|
# 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
|
end
|
||||||
|
|
||||||
def daily_totals(transactions, period: Period.last_30_days, currency: Current.family.currency)
|
def daily_totals(transactions, period: Period.last_30_days, currency: Current.family.currency)
|
||||||
|
|
Before Width: | Height: | Size: 653 B After Width: | Height: | Size: 653 B |
|
@ -1,4 +1,4 @@
|
||||||
<%= form_with model: transfer do |f| %>
|
<%= form_with model: transfer, data: { turbo_frame: "_top" } do |f| %>
|
||||||
<section>
|
<section>
|
||||||
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
|
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
|
||||||
<%= 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 %>
|
<%= 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 %>
|
|
@ -2,7 +2,7 @@
|
||||||
<details class="group flex items-center text-gray-900 p-4 text-sm font-medium">
|
<details class="group flex items-center text-gray-900 p-4 text-sm font-medium">
|
||||||
<summary class="flex items-center justify-between">
|
<summary class="flex items-center justify-between">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<%= button_to transfer_path(transfer),
|
<%= button_to account_transfer_path(transfer),
|
||||||
method: :delete,
|
method: :delete,
|
||||||
class: "flex items-center group/transfer",
|
class: "flex items-center group/transfer",
|
||||||
data: {
|
data: {
|
|
@ -78,7 +78,7 @@
|
||||||
<%= f.hidden_field :accountable_type %>
|
<%= f.hidden_field :accountable_type %>
|
||||||
<%= f.text_field :name, placeholder: t(".name.placeholder"), required: "required", label: t(".name.label"), autofocus: true %>
|
<%= 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") } %>
|
<%= 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" %>
|
<%= f.money_field :balance_money, label: t(".balance"), required: "required" %>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<%= t(".no_categories") %>
|
<%= t(".no_categories") %>
|
||||||
</div>
|
</div>
|
||||||
<% @categories.each do |category| %>
|
<% @categories.each do |category| %>
|
||||||
<%= render partial: "categories/dropdowns/row", locals: { category: } %>
|
<%= render partial: "category/dropdowns/row", locals: { category: } %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
|
@ -1,5 +1,5 @@
|
||||||
<%# locals: (date:, group:) %>
|
<%# locals: (date:, group:) %>
|
||||||
<div class="bg-gray-25 rounded-xl p-1 w-full" data-bulk-select-target="group">
|
<div id="date-group-<%= date %>" class="bg-gray-25 rounded-xl p-1 w-full" data-bulk-select-target="group">
|
||||||
<div class="py-2 px-4 flex items-center justify-between font-medium text-xs text-gray-500">
|
<div class="py-2 px-4 flex items-center justify-between font-medium text-xs text-gray-500">
|
||||||
<div class="flex pl-0.5 items-center gap-4">
|
<div class="flex pl-0.5 items-center gap-4">
|
||||||
<%= check_box_tag "#{date}_transactions_selection",
|
<%= check_box_tag "#{date}_transactions_selection",
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
|
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
|
||||||
<%= 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: :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" %>
|
<%= 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" %>
|
<%= lucide_icon "arrow-right-left", class: "w-5 h-5" %>
|
||||||
<%= tag.span t(".transfer") %>
|
<%= tag.span t(".transfer") %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
accept: t(".mark_transfers_confirm"),
|
accept: t(".mark_transfers_confirm"),
|
||||||
}
|
}
|
||||||
} do |f| %>
|
} do |f| %>
|
||||||
<button type="button" data-bulk-select-scope-param="bulk_update" data-action="bulk-select#submitBulkRequest" class="p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md" title="Mark as transfer">
|
<button id="bulk-transfer-btn" type="button" data-bulk-select-scope-param="bulk_update" data-action="bulk-select#submitBulkRequest" class="p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md" title="Mark as transfer">
|
||||||
<%= lucide_icon "arrow-right-left", class: "w-5 group-hover:text-white" %>
|
<%= lucide_icon "arrow-right-left", class: "w-5 group-hover:text-white" %>
|
||||||
</button>
|
</button>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
28
config/locales/views/account/transfers/en.yml
Normal file
28
config/locales/views/account/transfers/en.yml
Normal file
|
@ -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}
|
|
@ -3,27 +3,6 @@ en:
|
||||||
categories:
|
categories:
|
||||||
create:
|
create:
|
||||||
success: New transaction category created successfully
|
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: Edit category
|
edit: Edit category
|
||||||
form:
|
form:
|
||||||
|
|
15
config/locales/views/category/deletions/en.yml
Normal file
15
config/locales/views/category/deletions/en.yml
Normal file
|
@ -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
|
12
config/locales/views/category/dropdowns/en.yml
Normal file
12
config/locales/views/category/dropdowns/en.yml
Normal file
|
@ -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
|
15
config/locales/views/tag/deletions/en.yml
Normal file
15
config/locales/views/tag/deletions/en.yml
Normal file
|
@ -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
|
|
@ -3,18 +3,6 @@ en:
|
||||||
tags:
|
tags:
|
||||||
create:
|
create:
|
||||||
created: Tag created
|
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: Edit tag
|
edit: Edit tag
|
||||||
form:
|
form:
|
||||||
|
|
|
@ -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}
|
|
|
@ -38,18 +38,24 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :tags, except: %i[ show destroy ] do
|
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
|
end
|
||||||
|
|
||||||
resources :categories do
|
resources :categories do
|
||||||
resources :deletions, only: %i[ new create ], module: :categories
|
resources :deletions, only: %i[ new create ], module: :category
|
||||||
collection do
|
|
||||||
resource :dropdown, only: :show, module: :categories, as: :category_dropdown
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :merchants, only: %i[ index new create edit update destroy ]
|
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
|
resources :transactions do
|
||||||
collection do
|
collection do
|
||||||
post "bulk_delete"
|
post "bulk_delete"
|
||||||
|
@ -57,17 +63,14 @@ Rails.application.routes.draw do
|
||||||
post "bulk_update"
|
post "bulk_update"
|
||||||
post "mark_transfers"
|
post "mark_transfers"
|
||||||
post "unmark_transfers"
|
post "unmark_transfers"
|
||||||
|
|
||||||
scope module: :transactions, as: :transaction do
|
|
||||||
resources :rows, only: %i[ show update ]
|
|
||||||
resources :rules, only: %i[ index ]
|
|
||||||
end
|
|
||||||
end
|
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
|
collection do
|
||||||
get :summary
|
get :summary
|
||||||
get :list
|
get :list
|
||||||
|
@ -77,11 +80,8 @@ Rails.application.routes.draw do
|
||||||
post :sync
|
post :sync
|
||||||
end
|
end
|
||||||
|
|
||||||
scope module: :accounts do
|
resource :logo, only: :show, module: :account
|
||||||
resource :logo, only: :show
|
resources :valuations, shallow: true
|
||||||
end
|
|
||||||
|
|
||||||
resources :valuations
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :institutions, except: %i[ index show ]
|
resources :institutions, except: %i[ index show ]
|
||||||
|
|
5
db/migrate/20240620125026_rename_transfer_table.rb
Normal file
5
db/migrate/20240620125026_rename_transfer_table.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class RenameTransferTable < ActiveRecord::Migration[7.2]
|
||||||
|
def change
|
||||||
|
rename_table :transfers, :account_transfers
|
||||||
|
end
|
||||||
|
end
|
14
db/schema.rb
generated
14
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: 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
|
# 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"
|
||||||
|
@ -32,6 +32,11 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_20_122201) do
|
||||||
t.index ["account_id"], name: "index_account_balances_on_account_id"
|
t.index ["account_id"], name: "index_account_balances_on_account_id"
|
||||||
end
|
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|
|
create_table "accounts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||||
t.string "subtype"
|
t.string "subtype"
|
||||||
t.uuid "family_id", null: false
|
t.uuid "family_id", null: false
|
||||||
|
@ -313,11 +318,6 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_20_122201) do
|
||||||
t.index ["transfer_id"], name: "index_transactions_on_transfer_id"
|
t.index ["transfer_id"], name: "index_transactions_on_transfer_id"
|
||||||
end
|
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|
|
create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||||
t.uuid "family_id", null: false
|
t.uuid "family_id", null: false
|
||||||
t.string "first_name"
|
t.string "first_name"
|
||||||
|
@ -362,10 +362,10 @@ ActiveRecord::Schema[7.2].define(version: 2024_06_20_122201) do
|
||||||
add_foreign_key "merchants", "families"
|
add_foreign_key "merchants", "families"
|
||||||
add_foreign_key "taggings", "tags"
|
add_foreign_key "taggings", "tags"
|
||||||
add_foreign_key "tags", "families"
|
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", "accounts", on_delete: :cascade
|
||||||
add_foreign_key "transactions", "categories", on_delete: :nullify
|
add_foreign_key "transactions", "categories", on_delete: :nullify
|
||||||
add_foreign_key "transactions", "merchants"
|
add_foreign_key "transactions", "merchants"
|
||||||
add_foreign_key "transactions", "transfers"
|
|
||||||
add_foreign_key "users", "families"
|
add_foreign_key "users", "families"
|
||||||
add_foreign_key "valuations", "accounts", on_delete: :cascade
|
add_foreign_key "valuations", "accounts", on_delete: :cascade
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
|
||||||
class TransfersControllerTest < ActionDispatch::IntegrationTest
|
class Account::TransfersControllerTest < ActionDispatch::IntegrationTest
|
||||||
setup do
|
setup do
|
||||||
sign_in users(:family_admin)
|
sign_in users(:family_admin)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should get new" do
|
test "should get new" do
|
||||||
get new_transfer_url
|
get new_account_transfer_url
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can create transfers" do
|
test "can create transfers" do
|
||||||
assert_difference "Transfer.count", 1 do
|
assert_difference "Account::Transfer.count", 1 do
|
||||||
post transfers_url, params: {
|
post account_transfers_url, params: {
|
||||||
transfer: {
|
account_transfer: {
|
||||||
from_account_id: accounts(:checking).id,
|
from_account_id: accounts(:checking).id,
|
||||||
to_account_id: accounts(:savings).id,
|
to_account_id: accounts(:savings).id,
|
||||||
date: Date.current,
|
date: Date.current,
|
||||||
|
@ -26,8 +26,8 @@ class TransfersControllerTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can destroy transfer" do
|
test "can destroy transfer" do
|
||||||
assert_difference -> { Transfer.count } => -1, -> { Transaction.count } => 0 do
|
assert_difference -> { Account::Transfer.count } => -1, -> { Transaction.count } => 0 do
|
||||||
delete transfer_url(transfers(:credit_card_payment))
|
delete account_transfer_url(account_transfers(:credit_card_payment))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,6 +1,6 @@
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
|
||||||
class Categories::DeletionsControllerTest < ActionDispatch::IntegrationTest
|
class Category::DeletionsControllerTest < ActionDispatch::IntegrationTest
|
||||||
setup do
|
setup do
|
||||||
sign_in users(:family_admin)
|
sign_in users(:family_admin)
|
||||||
@category = categories(:food_and_drink)
|
@category = categories(:food_and_drink)
|
|
@ -1,6 +1,6 @@
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
|
||||||
class Tags::DeletionsControllerTest < ActionDispatch::IntegrationTest
|
class Tag::DeletionsControllerTest < ActionDispatch::IntegrationTest
|
||||||
setup do
|
setup do
|
||||||
sign_in @user = users(:family_admin)
|
sign_in @user = users(:family_admin)
|
||||||
@user_tags = @user.family.tags
|
@user_tags = @user.family.tags
|
2
test/fixtures/accounts.yml
vendored
2
test/fixtures/accounts.yml
vendored
|
@ -22,7 +22,7 @@ checking:
|
||||||
|
|
||||||
savings:
|
savings:
|
||||||
family: dylan_family
|
family: dylan_family
|
||||||
name: Savings account with valuation overrides
|
name: Savings account
|
||||||
balance: 19700
|
balance: 19700
|
||||||
accountable_type: Depository
|
accountable_type: Depository
|
||||||
accountable: depository_savings
|
accountable: depository_savings
|
||||||
|
|
|
@ -8,14 +8,14 @@ class TransferTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test "transfer valid if it has inflow and outflow from different accounts for the same amount" do
|
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?
|
assert transfer.valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
test "transfer must have 2 transactions" do
|
test "transfer must have 2 transactions" do
|
||||||
invalid_transfer_1 = Transfer.new transactions: [ @outflow ]
|
invalid_transfer_1 = Account::Transfer.new transactions: [ @outflow ]
|
||||||
invalid_transfer_2 = Transfer.new transactions: [ @inflow, @outflow, transactions(:savings_four) ]
|
invalid_transfer_2 = Account::Transfer.new transactions: [ @inflow, @outflow, transactions(:savings_four) ]
|
||||||
|
|
||||||
assert invalid_transfer_1.invalid?
|
assert invalid_transfer_1.invalid?
|
||||||
assert invalid_transfer_2.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
|
outflow = account.transactions.create! date: Date.current, name: "Outflow", amount: 100
|
||||||
|
|
||||||
assert_raise ActiveRecord::RecordInvalid do
|
assert_raise ActiveRecord::RecordInvalid do
|
||||||
Transfer.create! transactions: [ inflow, outflow ]
|
Account::Transfer.create! transactions: [ inflow, outflow ]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class TransferTest < ActiveSupport::TestCase
|
||||||
@inflow.update! marked_as_transfer: false
|
@inflow.update! marked_as_transfer: false
|
||||||
|
|
||||||
assert_raise ActiveRecord::RecordInvalid do
|
assert_raise ActiveRecord::RecordInvalid do
|
||||||
Transfer.create! transactions: [ @inflow, @outflow ]
|
Account::Transfer.create! transactions: [ @inflow, @outflow ]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class TransferTest < ActiveSupport::TestCase
|
||||||
@outflow.update! amount: 105
|
@outflow.update! amount: 105
|
||||||
|
|
||||||
assert_raises ActiveRecord::RecordInvalid do
|
assert_raises ActiveRecord::RecordInvalid do
|
||||||
Transfer.create! transactions: [ @inflow, @outflow ]
|
Account::Transfer.create! transactions: [ @inflow, @outflow ]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
82
test/system/transfers_test.rb
Normal file
82
test/system/transfers_test.rb
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue