1# frozen_string_literal: true
2
3require_relative "./oob"
4
5class Registration
6 def self.for(iq, customer, web_register_manager)
7 raise "TODO" if customer&.active?
8
9 EMPromise.resolve(customer&.registered?).then do |registered|
10 if registered
11 Registered.new(iq, registered.phone)
12 else
13 web_register_manager.choose_tel(iq).then do |(riq, tel)|
14 Activation.for(riq, customer, tel)
15 end
16 end
17 end
18 end
19
20 class Registered
21 def initialize(iq, tel)
22 @reply = iq.reply
23 @reply.status = :completed
24 @tel = tel
25 end
26
27 def write
28 @reply.note_type = :error
29 @reply.note_text = <<~NOTE
30 You are already registered with JMP number #{@tel}
31 NOTE
32 BLATHER << @reply
33 nil
34 end
35 end
36
37 class Activation
38 def self.for(iq, customer, tel)
39 return EMPromise.resolve(new(iq, customer, tel)) if customer
40
41 # Create customer_id
42 raise "TODO"
43 end
44
45 def initialize(iq, customer, tel)
46 @reply = iq.reply
47 reply.allowed_actions = [:next]
48
49 @customer = customer
50 @tel = tel
51 end
52
53 attr_reader :reply, :customer, :tel
54
55 FORM_FIELDS = [
56 {
57 var: "activation_method",
58 type: "list-single",
59 label: "Activate using",
60 required: true,
61 options: [
62 {
63 value: "bitcoin",
64 label: "Bitcoin"
65 },
66 {
67 value: "credit_card",
68 label: "Credit Card"
69 },
70 {
71 value: "code",
72 label: "Referral or Activation Code"
73 }
74 ]
75 },
76 {
77 var: "plan_name",
78 type: "list-single",
79 label: "What currency should your account balance be in?",
80 required: true,
81 options: [
82 {
83 value: "cad_beta_unlimited-v20210223",
84 label: "Canadian Dollars"
85 },
86 {
87 value: "usd_beta_unlimited-v20210223",
88 label: "United States Dollars"
89 }
90 ]
91 }
92 ].freeze
93
94 def write
95 form = reply.form
96 form.type = :form
97 form.title = "Activate JMP"
98 form.instructions = "Going to activate #{tel} (TODO RATE CTR)"
99 form.fields = FORM_FIELDS
100
101 COMMAND_MANAGER.write(reply).then { |iq|
102 Payment.for(iq, customer, tel)
103 }.then(&:write)
104 end
105 end
106
107 module Payment
108 def self.kinds
109 @kinds ||= {}
110 end
111
112 def self.for(iq, customer, tel)
113 plan_name = iq.form.field("plan_name").value.to_s
114 customer = customer.with_plan(plan_name)
115 kinds.fetch(iq.form.field("activation_method")&.value&.to_s&.to_sym) {
116 raise "Invalid activation method"
117 }.call(iq, customer, tel)
118 end
119
120 class Bitcoin
121 Payment.kinds[:bitcoin] = method(:new)
122
123 def initialize(iq, customer, tel)
124 @reply = iq.reply
125 reply.note_type = :info
126 reply.status = :completed
127
128 @customer = customer
129 @customer_id = customer.customer_id
130 @tel = tel
131 @addr = ELECTRUM.createnewaddress
132 end
133
134 attr_reader :reply, :customer_id, :tel
135
136 def save
137 EMPromise.all([
138 REDIS.mset(
139 "pending_tel_for-#{customer_id}", tel,
140 "pending_plan_for-#{customer_id}", @customer.plan_name
141 ),
142 @addr.then do |addr|
143 REDIS.sadd("jmp_customer_btc_addresses-#{customer_id}", addr)
144 end
145 ])
146 end
147
148 def note_text(amount, addr)
149 <<~NOTE
150 Activate your account by sending at least #{'%.6f' % amount} BTC to
151 #{addr}
152
153 You will receive a notification when your payment is complete.
154 NOTE
155 end
156
157 def write
158 EMPromise.all([
159 @addr,
160 save,
161 BTC_SELL_PRICES.public_send(@customer.currency.to_s.downcase)
162 ]).then do |(addr, _, rate)|
163 min = CONFIG[:activation_amount] / rate
164 reply.note_text = note_text(min, addr)
165 BLATHER << reply
166 nil
167 end
168 end
169 end
170
171 class CreditCard
172 Payment.kinds[:credit_card] = ->(*args) { self.for(*args) }
173
174 def self.for(iq, customer, tel)
175 customer.payment_methods.then do |payment_methods|
176 if payment_methods.default_payment_method
177 Activate.new(iq, customer, tel)
178 else
179 new(iq, customer, tel)
180 end
181 end
182 end
183
184 def initialize(iq, customer, tel)
185 @customer = customer
186 @tel = tel
187
188 @reply = iq.reply
189 @reply.allowed_actions = [:next]
190 @reply.note_type = :info
191 @reply.note_text = "#{oob.desc}: #{oob.url}"
192 end
193
194 attr_reader :reply
195
196 def oob
197 oob = OOB.find_or_create(@reply.command)
198 oob.url = CONFIG[:credit_card_url].call(
199 @reply.to.stripped.to_s,
200 @customer.customer_id
201 )
202 oob.desc = "Add credit card, then return here and choose next"
203 oob
204 end
205
206 def write
207 COMMAND_MANAGER.write(@reply).then do |riq|
208 CreditCard.for(riq, @customer, @tel)
209 end
210 end
211
212 class Activate
213 def initialize(_iq, _customer, _tel)
214 raise "TODO"
215 end
216 end
217 end
218 end
219end