diff --git a/app/controllers/transaction/rows_controller.rb b/app/controllers/account/transaction/rows_controller.rb similarity index 51% rename from app/controllers/transaction/rows_controller.rb rename to app/controllers/account/transaction/rows_controller.rb index 08f081b9..9bc823f3 100644 --- a/app/controllers/transaction/rows_controller.rb +++ b/app/controllers/account/transaction/rows_controller.rb @@ -1,4 +1,4 @@ -class Transaction::RowsController < ApplicationController +class Account::Transaction::RowsController < ApplicationController before_action :set_transaction, only: %i[ show update ] def show @@ -7,7 +7,7 @@ class Transaction::RowsController < ApplicationController def update @transaction.update! transaction_params - redirect_to transaction_row_path(@transaction) + redirect_to account_transaction_row_path(@transaction.account, @transaction) end private @@ -17,6 +17,6 @@ class Transaction::RowsController < ApplicationController end def set_transaction - @transaction = Current.family.transactions.find(params[:id]) + @transaction = Current.family.accounts.find(params[:account_id]).transactions.find(params[:transaction_id]) end end diff --git a/app/controllers/account/transaction/rules_controller.rb b/app/controllers/account/transaction/rules_controller.rb new file mode 100644 index 00000000..704b2119 --- /dev/null +++ b/app/controllers/account/transaction/rules_controller.rb @@ -0,0 +1,6 @@ +class Account::Transaction::RulesController < ApplicationController + layout "with_sidebar" + + def index + end +end diff --git a/app/controllers/account/transactions_controller.rb b/app/controllers/account/transactions_controller.rb new file mode 100644 index 00000000..184725f6 --- /dev/null +++ b/app/controllers/account/transactions_controller.rb @@ -0,0 +1,44 @@ +class Account::TransactionsController < ApplicationController + layout "with_sidebar" + + before_action :set_account + before_action :set_transaction, only: %i[ show update destroy ] + + def index + @transactions = @account.transactions.ordered + end + + def show + end + + def update + @transaction.update! transaction_params + @transaction.sync_account_later + + redirect_back_or_to account_transaction_url(@transaction.account, @transaction), notice: t(".success") + end + + def destroy + @transaction.destroy! + @transaction.sync_account_later + redirect_back_or_to account_url(@transaction.account), notice: t(".success") + end + + private + + def set_account + @account = Current.family.accounts.find(params[:account_id]) + end + + def set_transaction + @transaction = @account.transactions.find(params[:id]) + end + + def search_params + params.fetch(:q, {}).permit(:start_date, :end_date, :search, accounts: [], account_ids: [], categories: [], merchants: []) + end + + def transaction_params + params.require(:transaction).permit(:name, :date, :amount, :currency, :notes, :excluded, :category_id, :merchant_id, tag_ids: []) + end +end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 5b8c5eed..42cdd1f2 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -21,7 +21,7 @@ class PagesController < ApplicationController @accounts = Current.family.accounts @account_groups = @accounts.by_group(period: @period, currency: Current.family.currency) - @transactions = Current.family.transactions.limit(5).order(date: :desc) + @transactions = Current.family.transactions.limit(6).order(date: :desc) # TODO: Placeholders for trendlines placeholder_series_data = 10.times.map do |i| diff --git a/app/controllers/transaction/rules_controller.rb b/app/controllers/transaction/rules_controller.rb deleted file mode 100644 index 7c7b157a..00000000 --- a/app/controllers/transaction/rules_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Transaction::RulesController < ApplicationController - layout "with_sidebar" - - def index - end -end diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index 98be1c39..ed38b535 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -1,8 +1,6 @@ class TransactionsController < ApplicationController layout "with_sidebar" - before_action :set_transaction, only: %i[ show edit update destroy ] - def index @q = search_params result = Current.family.transactions.search(@q).ordered @@ -15,41 +13,22 @@ class TransactionsController < ApplicationController } end - def show - end - def new - @transaction = Transaction.new.tap do |txn| + @transaction = Account::Transaction.new.tap do |txn| if params[:account_id] txn.account = Current.family.accounts.find(params[:account_id]) end end end - def edit - end - def create @transaction = Current.family.accounts - .find(params[:transaction][:account_id]) - .transactions.build(transaction_params.merge(amount: amount)) + .find(params[:transaction][:account_id]) + .transactions + .create!(transaction_params.merge(amount: amount)) - @transaction.save! @transaction.sync_account_later - redirect_to transactions_url, notice: t(".success") - end - - def update - @transaction.update! transaction_params - @transaction.sync_account_later - - redirect_to transaction_url(@transaction), notice: t(".success") - end - - def destroy - @transaction.destroy! - @transaction.sync_account_later - redirect_to transactions_url, notice: t(".success") + redirect_back_or_to account_path(@transaction.account), notice: t(".success") end def bulk_delete @@ -90,10 +69,6 @@ class TransactionsController < ApplicationController private - def set_transaction - @transaction = Current.family.transactions.find(params[:id]) - end - def amount if nature.income? transaction_params[:amount].to_d * -1 @@ -119,6 +94,6 @@ class TransactionsController < ApplicationController end def transaction_params - params.require(:transaction).permit(:name, :date, :amount, :currency, :notes, :excluded, :category_id, :merchant_id, tag_ids: []) + params.require(:transaction).permit(:name, :date, :amount, :currency, :category_id, tag_ids: []) end end diff --git a/app/helpers/transactions/searches_helper.rb b/app/helpers/account/transaction/searches_helper.rb similarity index 96% rename from app/helpers/transactions/searches_helper.rb rename to app/helpers/account/transaction/searches_helper.rb index 09bd882a..09d3e0dc 100644 --- a/app/helpers/transactions/searches_helper.rb +++ b/app/helpers/account/transaction/searches_helper.rb @@ -1,4 +1,4 @@ -module Transactions::SearchesHelper +module Account::Transaction::SearchesHelper def transaction_search_filters [ { key: "account_filter", name: "Account", icon: "layers" }, diff --git a/app/helpers/transactions_helper.rb b/app/helpers/account/transactions_helper.rb similarity index 57% rename from app/helpers/transactions_helper.rb rename to app/helpers/account/transactions_helper.rb index 67758978..bc888360 100644 --- a/app/helpers/transactions_helper.rb +++ b/app/helpers/account/transactions_helper.rb @@ -1,23 +1,4 @@ -module TransactionsHelper - def transactions_group(date, transactions, transaction_partial_path = "transactions/transaction") - header_left = content_tag :span do - "#{date.strftime('%b %d, %Y')} · #{transactions.size}".html_safe - end - - header_right = content_tag :span do - format_money(-transactions.sum(&:amount_money)) - end - - header = header_left.concat(header_right) - - content = render partial: transaction_partial_path, collection: transactions - - render partial: "shared/list_group", locals: { - header: header, - content: content - } - end - +module Account::TransactionsHelper def unconfirmed_transfer?(transaction) transaction.marked_as_transfer && transaction.transfer.nil? end diff --git a/app/helpers/account/valuations_helper.rb b/app/helpers/account/valuations_helper.rb index e1a93dde..5143e43d 100644 --- a/app/helpers/account/valuations_helper.rb +++ b/app/helpers/account/valuations_helper.rb @@ -1,6 +1,6 @@ module Account::ValuationsHelper def valuation_icon(valuation) - if valuation.first_of_series? + if valuation.oldest? "keyboard" elsif valuation.trend.direction.up? "arrow-up" @@ -12,7 +12,7 @@ module Account::ValuationsHelper end def valuation_style(valuation) - color = valuation.first_of_series? ? "#D444F1" : valuation.trend.color + color = valuation.oldest? ? "#D444F1" : valuation.trend.color <<-STYLE.strip background-color: color-mix(in srgb, #{color} 5%, white); diff --git a/app/models/transaction.rb b/app/models/account/transaction.rb similarity index 88% rename from app/models/transaction.rb rename to app/models/account/transaction.rb index bad2aaf6..df4b4621 100644 --- a/app/models/transaction.rb +++ b/app/models/account/transaction.rb @@ -1,4 +1,4 @@ -class Transaction < ApplicationRecord +class Account::Transaction < ApplicationRecord include Monetizable monetize :amount @@ -17,22 +17,22 @@ class Transaction < ApplicationRecord scope :active, -> { where(excluded: false) } scope :inflows, -> { where("amount <= 0") } scope :outflows, -> { where("amount > 0") } - scope :by_name, ->(name) { where("transactions.name ILIKE ?", "%#{name}%") } + scope :by_name, ->(name) { where("account_transactions.name ILIKE ?", "%#{name}%") } scope :with_categories, ->(categories) { joins(:category).where(categories: { name: categories }) } scope :with_accounts, ->(accounts) { joins(:account).where(accounts: { name: accounts }) } scope :with_account_ids, ->(account_ids) { joins(:account).where(accounts: { id: account_ids }) } scope :with_merchants, ->(merchants) { joins(:merchant).where(merchants: { name: merchants }) } - scope :on_or_after_date, ->(date) { where("transactions.date >= ?", date) } - scope :on_or_before_date, ->(date) { where("transactions.date <= ?", date) } + scope :on_or_after_date, ->(date) { where("account_transactions.date >= ?", date) } + scope :on_or_before_date, ->(date) { where("account_transactions.date <= ?", date) } scope :with_converted_amount, ->(currency = Current.family.currency) { # Join with exchange rates to convert the amount to the given currency # If no rate is available, exclude the transaction from the results select( - "transactions.*", - "transactions.amount * COALESCE(er.rate, 1) AS converted_amount" + "account_transactions.*", + "account_transactions.amount * COALESCE(er.rate, 1) AS converted_amount" ) - .joins(sanitize_sql_array([ "LEFT JOIN exchange_rates er ON transactions.date = er.date AND transactions.currency = er.base_currency AND er.converted_currency = ?", currency ])) - .where("er.rate IS NOT NULL OR transactions.currency = ?", currency) + .joins(sanitize_sql_array([ "LEFT JOIN exchange_rates er ON account_transactions.date = er.date AND account_transactions.currency = er.base_currency AND er.converted_currency = ?", currency ])) + .where("er.rate IS NOT NULL OR account_transactions.currency = ?", currency) } def inflow? diff --git a/app/models/account/valuation.rb b/app/models/account/valuation.rb index ddbb519c..ffe21abe 100644 --- a/app/models/account/valuation.rb +++ b/app/models/account/valuation.rb @@ -15,14 +15,10 @@ class Account::Valuation < ApplicationRecord @trend ||= create_trend end - def first_of_series? + def oldest? account.valuations.chronological.limit(1).pluck(:date).first == self.date end - def last_of_series? - account.valuations.reverse_chronological.limit(1).pluck(:date).first == self.date - end - def sync_account_later if destroyed? sync_start_date = previous_valuation&.date diff --git a/app/models/category.rb b/app/models/category.rb index b846ca51..cfcab4ef 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,5 +1,5 @@ class Category < ApplicationRecord - has_many :transactions, dependent: :nullify + has_many :transactions, dependent: :nullify, class_name: "Account::Transaction" belongs_to :family validates :name, :color, :family, presence: true diff --git a/app/models/family.rb b/app/models/family.rb index 1159fd87..378dd76e 100644 --- a/app/models/family.rb +++ b/app/models/family.rb @@ -3,7 +3,7 @@ class Family < ApplicationRecord has_many :tags, dependent: :destroy has_many :accounts, dependent: :destroy has_many :institutions, dependent: :destroy - has_many :transactions, through: :accounts + has_many :transactions, through: :accounts, class_name: "Account::Transaction" has_many :imports, through: :accounts has_many :categories, dependent: :destroy has_many :merchants, dependent: :destroy @@ -40,9 +40,9 @@ class Family < ApplicationRecord "COALESCE(SUM(amount) FILTER (WHERE amount > 0), 0) AS spending", "COALESCE(SUM(-amount) FILTER (WHERE amount < 0), 0) AS income" ) - .where("transactions.date >= ?", period.date_range.begin) - .where("transactions.date <= ?", period.date_range.end) - .where("transactions.marked_as_transfer = ?", false) + .where("account_transactions.date >= ?", period.date_range.begin) + .where("account_transactions.date <= ?", period.date_range.end) + .where("account_transactions.marked_as_transfer = ?", false) .group("id") .to_a @@ -60,7 +60,7 @@ class Family < ApplicationRecord end def snapshot_transactions - rolling_totals = Transaction.daily_rolling_totals(transactions, period: Period.last_30_days, currency: self.currency) + rolling_totals = Account::Transaction.daily_rolling_totals(transactions, period: Period.last_30_days, currency: self.currency) spending = [] income = [] diff --git a/app/models/merchant.rb b/app/models/merchant.rb index 5e657763..3d1448e2 100644 --- a/app/models/merchant.rb +++ b/app/models/merchant.rb @@ -1,5 +1,5 @@ class Merchant < ApplicationRecord - has_many :transactions, dependent: :nullify + has_many :transactions, dependent: :nullify, class_name: "Account::Transaction" belongs_to :family validates :name, :color, :family, presence: true diff --git a/app/models/tag.rb b/app/models/tag.rb index 6dd5988c..eab4d866 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -1,7 +1,7 @@ class Tag < ApplicationRecord belongs_to :family has_many :taggings, dependent: :destroy - has_many :transactions, through: :taggings, source: :taggable, source_type: "Transaction" + has_many :transactions, through: :taggings, source: :taggable, source_type: "Account::Transaction" validates :name, presence: true, uniqueness: { scope: :family } diff --git a/app/views/account/transaction/rows/show.html.erb b/app/views/account/transaction/rows/show.html.erb new file mode 100644 index 00000000..473d8200 --- /dev/null +++ b/app/views/account/transaction/rows/show.html.erb @@ -0,0 +1 @@ +<%= render "account/transactions/transaction", transaction: @transaction %> diff --git a/app/views/transaction/rules/index.html.erb b/app/views/account/transaction/rules/index.html.erb similarity index 99% rename from app/views/transaction/rules/index.html.erb rename to app/views/account/transaction/rules/index.html.erb index 6e3162a7..62222550 100644 --- a/app/views/transaction/rules/index.html.erb +++ b/app/views/account/transaction/rules/index.html.erb @@ -1,6 +1,7 @@ <% content_for :sidebar do %> <%= render "settings/nav" %> <% end %> +
<%= t(".no_transactions") %>
+ <% else %> +<%= t(".no_valuations") %>
+ <% end %> +No transactions for this account yet.
- <% else %> -Transfer
-<%= t(".greeting", name: Current.user.first_name ) %>
- <% if !@accounts.blank? %> + <% unless @accounts.blank? %><%= t(".subtitle") %>
<% end %><%= link_to t(".view_all"), transactions_path %>
diff --git a/app/views/pages/dashboard/transactions/_transaction.html.erb b/app/views/pages/dashboard/transactions/_transaction.html.erb deleted file mode 100644 index 49fc3be3..00000000 --- a/app/views/pages/dashboard/transactions/_transaction.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -