diff --git a/forms/admin_menu.rb b/forms/admin_menu.rb index aeb8b7ddc1b36ef9b7b9fc7dc5fed41e985dcf21..650642e6c101f4c1687ccf2077a06c8c5a777203 100644 --- a/forms/admin_menu.rb +++ b/forms/admin_menu.rb @@ -11,6 +11,7 @@ field( { value: "info", label: "Customer Info" }, { value: "financial", label: "Customer Billing Information" }, { value: "bill_plan", label: "Bill Customer" }, - { value: "cancel_account", label: "Cancel Customer" } + { value: "cancel_account", label: "Cancel Customer" }, + { value: "undo", label: "Undo" } ] ) diff --git a/lib/admin_command.rb b/lib/admin_command.rb index 84378e9d4b16bcff840ec8ca2e086080f12551a6..955db83831aa223822c37e95a5fcb29fe6b6c482 100644 --- a/lib/admin_command.rb +++ b/lib/admin_command.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require_relative "admin_action_repo" require_relative "admin_actions/cancel" require_relative "admin_actions/financial" require_relative "bill_plan_command" @@ -8,21 +9,26 @@ require_relative "financial_info" require_relative "form_template" class AdminCommand - def self.for(target_customer, customer_repo) + def self.for( + target_customer, + customer_repo, + admin_action_repo=AdminActionRepo.new + ) if target_customer - new(target_customer, customer_repo) + new(target_customer, customer_repo, admin_action_repo) else Command.reply { |reply| reply.allowed_actions = [:next, :complete] reply.note_type = :error reply.note_text = "Customer Not Found" - }.then { NoUser.new(customer_repo) } + }.then { NoUser.new(customer_repo, admin_action_repo) } end end class NoUser - def initialize(customer_repo) + def initialize(customer_repo, admin_action_repo=AdminActionRepo.new) @customer_repo = customer_repo + @admin_action_repo = admin_action_repo end def start @@ -32,14 +38,20 @@ class AdminCommand }.then { |response| CustomerInfoForm.new(@customer_repo).find_customer(response) }.then { |customer| - AdminCommand.for(customer, @customer_repo).then(&:start) + AdminCommand.for(customer, @customer_repo, @admin_action_repo) + .then(&:start) } end end - def initialize(target_customer, customer_repo) + def initialize( + target_customer, + customer_repo, + admin_action_repo=AdminActionRepo.new + ) @target_customer = target_customer @customer_repo = customer_repo + @admin_action_repo = admin_action_repo end def start @@ -76,7 +88,8 @@ class AdminCommand def new_context(q) CustomerInfoForm.new(@customer_repo) .parse_something(q).then do |new_customer| - AdminCommand.for(new_customer, @customer_repo).then(&:start) + AdminCommand.for(new_customer, @customer_repo, @admin_action_repo) + .then(&:start) end end @@ -89,6 +102,40 @@ class AdminCommand BillPlanCommand.for(@target_customer).call end + class Undoable + def initialize(klass) + @klass = klass + end + + def call(customer, admin_action_repo:, **) + @klass.for(customer, reply: method(:reply)).then { |action| + Command.customer.then { |actor| + action.with(actor_id: actor.customer_id).perform.then do |performed| + admin_action_repo.create(performed) + end + } + }.then(method(:success), method(:failure)) + end + + def reply(form=nil, note_type: nil, note_text: nil) + Command.reply { |reply| + reply.allowed_actions = [:next, :complete] + reply.command << form if form + reply.note_type = note_type if note_type + reply.note_text = note_text if note_text + } + end + + def success(action) + reply(note_type: :info, note_text: "Action #{action.id}: #{action}") + end + + def failure(err) + LOG.error "Action Failure", err + reply(note_type: :error, note_text: "Action Failed: #{err}") + end + end + class Simple def initialize(klass) @klass = klass @@ -112,9 +159,22 @@ class AdminCommand end end + class Undo + def self.for(target_customer, **) + AdminActionRepo.new + .find(1, customer_id: target_customer.customer_id) + .then { |actions| + raise "No actions found" if actions.empty? + + actions.first.undo + } + end + end + [ [:cancel_account, Simple.new(AdminAction::CancelCustomer)], - [:financial, Simple.new(AdminAction::Financial)] + [:financial, Simple.new(AdminAction::Financial)], + [:undo, Undoable.new(Undo)] ].each do |action, handler| define_method("action_#{action}") do handler.call( diff --git a/test/test_admin_command.rb b/test/test_admin_command.rb index 1b31f3dc530cfe91f1079e0335eb683ac16d76ad..506cc3a1b5fe1dc2a1f8ad1f9dc4791de2abf734 100644 --- a/test/test_admin_command.rb +++ b/test/test_admin_command.rb @@ -4,6 +4,7 @@ require "admin_command" BackendSgx::IQ_MANAGER = Minitest::Mock.new Customer::BLATHER = Minitest::Mock.new +AdminActionRepo::REDIS = Minitest::Mock.new class AdminCommandTest < Minitest::Test def admin_command(tel="+15556667777")