1# frozen_string_literal: true
2
3require_relative "admin_actions/cancel"
4require_relative "admin_actions/financial"
5require_relative "bill_plan_command"
6require_relative "customer_info_form"
7require_relative "financial_info"
8require_relative "form_template"
9
10class AdminCommand
11 def self.for(target_customer, customer_repo)
12 if target_customer
13 new(target_customer, customer_repo)
14 else
15 Command.reply { |reply|
16 reply.allowed_actions = [:next, :complete]
17 reply.note_type = :error
18 reply.note_text = "Customer Not Found"
19 }.then { NoUser.new(customer_repo) }
20 end
21 end
22
23 class NoUser
24 def initialize(customer_repo)
25 @customer_repo = customer_repo
26 end
27
28 def start
29 Command.reply { |reply|
30 reply.allowed_actions = [:next]
31 reply.command << FormTemplate.render("customer_picker")
32 }.then { |response|
33 CustomerInfoForm.new(@customer_repo).find_customer(response)
34 }.then { |customer|
35 AdminCommand.for(customer, @customer_repo).then(&:start)
36 }
37 end
38 end
39
40 def initialize(target_customer, customer_repo)
41 @target_customer = target_customer
42 @customer_repo = customer_repo
43 end
44
45 def start
46 @target_customer.admin_info.then { |info|
47 reply(info.form)
48 }.then { menu_or_done }
49 end
50
51 def reply(form)
52 Command.reply { |reply|
53 reply.allowed_actions = [:next, :complete]
54 reply.command << form
55 }
56 end
57
58 def menu_or_done(command_action=:execute)
59 return Command.finish("Done") if command_action == :complete
60
61 reply(FormTemplate.render("admin_menu")).then do |response|
62 if response.form.field("action")
63 handle(response.form.field("action").value, response.action)
64 end
65 end
66 end
67
68 def handle(action, command_action)
69 if respond_to?("action_#{action}")
70 send("action_#{action}")
71 else
72 new_context(action)
73 end.then { menu_or_done(command_action) }
74 end
75
76 def new_context(q)
77 CustomerInfoForm.new(@customer_repo)
78 .parse_something(q).then do |new_customer|
79 AdminCommand.for(new_customer, @customer_repo).then(&:start)
80 end
81 end
82
83 def action_info
84 # Refresh the data
85 new_context(@target_customer.customer_id)
86 end
87
88 def action_bill_plan
89 BillPlanCommand.for(@target_customer).call
90 end
91
92 class Simple
93 def initialize(klass)
94 @klass = klass
95 end
96
97 def call(customer_id, customer_repo:, **)
98 @klass.call(
99 customer_id,
100 reply: method(:reply),
101 customer_repo: customer_repo
102 )
103 end
104
105 def reply(form=nil, note_type: nil, note_text: nil)
106 Command.reply { |reply|
107 reply.allowed_actions = [:next, :complete]
108 reply.command << form if form
109 reply.note_type = note_type if note_type
110 reply.note_text = note_text if note_text
111 }
112 end
113 end
114
115 [
116 [:cancel_account, Simple.new(AdminAction::CancelCustomer)],
117 [:financial, Simple.new(AdminAction::Financial)]
118 ].each do |action, handler|
119 define_method("action_#{action}") do
120 handler.call(
121 @target_customer,
122 admin_action_repo: @admin_action_repo,
123 customer_repo: @customer_repo
124 )
125 end
126 end
127end