1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-10 07:55:21 +02:00

Add rule deletions, get rules working

This commit is contained in:
Zach Gollwitzer 2025-04-09 17:45:23 -04:00
parent 757a1c019d
commit 3b464b97aa
12 changed files with 64 additions and 16 deletions

View file

@ -368,6 +368,10 @@
@apply border border-transparent text-gray-900 hover:bg-gray-100;
}
.btn--outline-destructive {
@apply border border-alpha-black-200 text-red-500 hover:bg-gray-50 disabled:text-red-300;
}
.btn--destructive {
@apply bg-red-500 text-white hover:bg-red-600 disabled:bg-red-50 disabled:hover:bg-red-50 disabled:text-red-400;
}

View file

@ -47,7 +47,12 @@ class RulesController < ApplicationController
def destroy
@rule.destroy
redirect_to rules_path
redirect_to rules_path, notice: "Rule deleted"
end
def destroy_all
Current.family.rules.destroy_all
redirect_to rules_path, notice: "All rules deleted"
end
private

View file

@ -36,7 +36,7 @@ class Rule < ApplicationRecord
end
end
def apply
def matching_resources_scope
scope = registry.resource_scope
# 1. Prepare the query with joins required by conditions
@ -55,9 +55,12 @@ class Rule < ApplicationRecord
scope = condition.apply(scope)
end
# 3. Apply the actions to the resources resulting from the query
scope
end
def apply
actions.each do |action|
action.apply(scope)
action.apply(matching_resources_scope)
end
end

View file

@ -8,8 +8,10 @@ class Rule::ActionExecutor::SetTransactionCategory < Rule::ActionExecutor
end
def execute(transaction_scope, value = nil)
category = family.categories.find_by_id(value)
transaction_scope.update_all(
category_id: value,
category_id: category.id,
updated_at: Time.current
)
end

View file

@ -8,6 +8,10 @@ class Rule::ActionExecutor::SetTransactionTags < Rule::ActionExecutor
end
def execute(transaction_scope, value = nil)
# TODO
tag = family.tags.find_by_id(value)
transaction_scope.each do |transaction|
transaction.update(tags: [ tag ])
end
end
end

View file

@ -61,7 +61,7 @@ class Rule::ConditionFilter
end
def build_sanitized_where_condition(field, operator, value)
sanitized_value = operator == "like" ? ActiveRecord::Base.sanitize_sql_like(value) : value
sanitized_value = operator == "like" ? "%#{ActiveRecord::Base.sanitize_sql_like(value)}%" : value
ActiveRecord::Base.sanitize_sql_for_conditions([
"#{field} #{sanitize_operator(operator)} ?",
@ -71,6 +71,11 @@ class Rule::ConditionFilter
def sanitize_operator(operator)
raise UnsupportedOperatorError, "Unsupported operator: #{operator} for type: #{type}" unless operators.include?(operator)
operator
if operator == "like"
"ILIKE"
else
operator
end
end
end

View file

@ -8,7 +8,7 @@ class Rule::ConditionFilter::TransactionAmount < Rule::ConditionFilter
end
def apply(scope, operator, value)
expression = build_sanitized_where_condition("account_entries.amount", operator, value.to_d)
expression = build_sanitized_where_condition("ABS(account_entries.amount)", operator, value.to_d)
scope.where(expression)
end
end

View file

@ -27,7 +27,14 @@
<%= contextual_menu icon: "more-vertical", id: "chat-menu" do %>
<%= contextual_menu_item "Edit", url: edit_rule_path(rule), icon: "pencil", turbo_frame: "modal" %>
<%= contextual_menu_destructive_item "Delete", rule_path(rule), turbo_confirm: "Are you sure you want to delete this rule?" %>
<% turbo_confirm = {
title: "Delete rule",
body: "Are you sure you want to delete this rule? Data affected by this rule will no longer be automatically updated. This action cannot be undone.",
accept: "Delete rule",
} %>
<%= contextual_menu_destructive_item "Delete", rule_path(rule), turbo_confirm: turbo_confirm %>
<% end %>
</div>
</div>

View file

@ -1,10 +1,24 @@
<header class="flex items-center justify-between">
<h1 class="text-primary text-xl font-medium">Rules</h1>
<%= link_to new_rule_path(resource_type: "transaction"), class: "btn btn--primary flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= lucide_icon "plus", class: "w-5 h-5" %>
<p>New rule</p>
<% end %>
<% turbo_confirm = {
title: "Delete all rules",
body: "Are you sure you want to delete all rules? This action cannot be undone.",
accept: "Delete all rules",
} %>
<div class="flex items-center gap-2">
<% if @rules.any? %>
<%= contextual_menu do %>
<%= contextual_menu_destructive_item "Delete all rules", destroy_all_rules_path, turbo_confirm: turbo_confirm %>
<% end %>
<% end %>
<%= link_to new_rule_path(resource_type: "transaction"), class: "btn btn--primary flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= lucide_icon "plus", class: "w-5 h-5" %>
<p>New rule</p>
<% end %>
</div>
</header>
<div class="bg-white shadow-border-xs rounded-xl p-4">

View file

@ -11,7 +11,6 @@
<%= t(".body_html") %>
</div>
</div>
<button id="turbo-confirm-accept" class="w-full text-red-600 rounded-xl text-center p-[10px] border mb-2" value="confirm"><%= t(".accept") %></button>
<button class="w-full rounded-xl text-center p-[10px] border" value="cancel"><%= t(".cancel") %></button>
<button id="turbo-confirm-accept" class="btn btn--outline-destructive w-full mb-2" value="confirm"><%= t(".accept") %></button>
</form>
</dialog>

View file

@ -3,6 +3,7 @@
<div class="flex items-center gap-5">
<div class="flex items-center gap-2">
<%= contextual_menu do %>
<%= contextual_menu_item "Edit rules", url: rules_path, icon: "git-branch" %>
<%= contextual_menu_modal_action_item t(".edit_categories"), categories_path, icon: "shapes", turbo_frame: :_top %>
<%= contextual_menu_modal_action_item t(".edit_tags"), tags_path, icon: "tags", turbo_frame: :_top %>
<%= contextual_menu_modal_action_item t(".edit_merchants"), family_merchants_path, icon: "store", turbo_frame: :_top %>

View file

@ -145,6 +145,10 @@ Rails.application.routes.draw do
end
resources :rules, except: :show do
collection do
delete :destroy_all
end
resources :triggers, only: :new
resources :actions, only: :new
end