diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb index 83bddbf3..c58713d4 100644 --- a/app/helpers/categories_helper.rb +++ b/app/helpers/categories_helper.rb @@ -4,4 +4,8 @@ module CategoriesHelper name: "Uncategorized", color: Category::UNCATEGORIZED_COLOR end + + def family_categories + [ null_category ].concat(Current.family.categories.alphabetically) + end end diff --git a/app/models/account/transaction.rb b/app/models/account/transaction.rb index bf08ef0c..52a0f9bd 100644 --- a/app/models/account/transaction.rb +++ b/app/models/account/transaction.rb @@ -13,7 +13,19 @@ class Account::Transaction < ApplicationRecord class << self def search(params) query = all - query = query.joins(:category).where(categories: { name: params[:categories] }) if params[:categories].present? + if params[:categories].present? + if params[:categories].exclude?("Uncategorized") + query = query + .joins(:category) + .where(categories: { name: params[:categories] }) + else + query = query + .left_joins(:category) + .where(categories: { name: params[:categories] }) + .or(query.where(category_id: nil)) + end + end + query = query.joins(:merchant).where(merchants: { name: params[:merchants] }) if params[:merchants].present? if params[:tags].present? diff --git a/app/views/transactions/searches/filters/_category_filter.html.erb b/app/views/transactions/searches/filters/_category_filter.html.erb index 5f399126..5212bbe4 100644 --- a/app/views/transactions/searches/filters/_category_filter.html.erb +++ b/app/views/transactions/searches/filters/_category_filter.html.erb @@ -5,7 +5,7 @@ <%= lucide_icon("search", class: "w-5 h-5 text-gray-500 absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
- <% Current.family.categories.alphabetically.each do |category| %> + <% family_categories.each do |category| %>
<%= form.check_box :categories, { diff --git a/test/system/transactions_test.rb b/test/system/transactions_test.rb index 956e800b..622f0b81 100644 --- a/test/system/transactions_test.rb +++ b/test/system/transactions_test.rb @@ -6,7 +6,7 @@ class TransactionsTest < ApplicationSystemTestCase Account::Entry.delete_all # clean slate - create_transaction("one", 12.days.ago.to_date, 100) + @uncategorized_transaction = create_transaction("one", 12.days.ago.to_date, 100) create_transaction("two", 10.days.ago.to_date, 100) create_transaction("three", 9.days.ago.to_date, 100) create_transaction("four", 8.days.ago.to_date, 100) @@ -61,6 +61,30 @@ class TransactionsTest < ApplicationSystemTestCase end end + test "can filter uncategorized transactions" do + find("#transaction-filters-button").click + + within "#transaction-filters-menu" do + click_button "Category" + check("Uncategorized") + click_button "Apply" + end + + assert_selector "#" + dom_id(@uncategorized_transaction), count: 1 + assert_no_selector("#" + dom_id(@transaction)) + + find("#transaction-filters-button").click + + within "#transaction-filters-menu" do + click_button "Category" + check(@transaction.account_transaction.category.name) + click_button "Apply" + end + + assert_selector "#" + dom_id(@transaction), count: 1 + assert_selector "#" + dom_id(@uncategorized_transaction), count: 1 + end + test "all filters work and empty state shows if no match" do find("#transaction-filters-button").click