diff --git a/app/models/rule/action_executor/set_transaction_merchant.rb b/app/models/rule/action_executor/set_transaction_merchant.rb new file mode 100644 index 00000000..492ece52 --- /dev/null +++ b/app/models/rule/action_executor/set_transaction_merchant.rb @@ -0,0 +1,30 @@ +class Rule::ActionExecutor::SetTransactionMerchant < Rule::ActionExecutor + def type + "select" + end + + def options + family.merchants.pluck(:name, :id) + end + + def execute(transaction_scope, value: nil, ignore_attribute_locks: false) + merchant = family.merchants.find_by_id(value) + return unless merchant + + scope = transaction_scope + unless ignore_attribute_locks + scope = scope.enrichable(:merchant_id) + end + + scope.each do |txn| + Rule.transaction do + txn.log_enrichment!( + attribute_name: "merchant_id", + attribute_value: merchant.id, + source: "rule" + ) + txn.update!(merchant: merchant) + end + end + end +end diff --git a/app/models/rule/registry/transaction_resource.rb b/app/models/rule/registry/transaction_resource.rb index 1bcdf8a7..628d8cde 100644 --- a/app/models/rule/registry/transaction_resource.rb +++ b/app/models/rule/registry/transaction_resource.rb @@ -14,7 +14,8 @@ class Rule::Registry::TransactionResource < Rule::Registry def action_executors enabled_executors = [ Rule::ActionExecutor::SetTransactionCategory.new(rule), - Rule::ActionExecutor::SetTransactionTags.new(rule) + Rule::ActionExecutor::SetTransactionTags.new(rule), + Rule::ActionExecutor::SetTransactionMerchant.new(rule) ] if ai_enabled? diff --git a/test/models/rule/action_test.rb b/test/models/rule/action_test.rb index 6cab0bd9..61ee6425 100644 --- a/test/models/rule/action_test.rb +++ b/test/models/rule/action_test.rb @@ -58,4 +58,25 @@ class Rule::ActionTest < ActiveSupport::TestCase assert_equal [ tag ], transaction.reload.tags end end + + test "set_transaction_merchant" do + merchant = @family.merchants.create!(name: "Rule test merchant") + + # Does not modify transactions that are locked (user edited them) + @txn1.lock!(:merchant_id) + + action = Rule::Action.new( + rule: @transaction_rule, + action_type: "set_transaction_merchant", + value: merchant.id + ) + + action.apply(@rule_scope) + + assert_not_equal merchant.id, @txn1.reload.merchant_id + + [ @txn2, @txn3 ].each do |transaction| + assert_equal merchant.id, transaction.reload.merchant_id + end + end end