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.for(iq, customer, tel)
109 case iq.form.field("activation_method")&.value&.to_s
110 when "bitcoin"
111 Bitcoin.new(iq, customer, tel)
112 when "credit_card"
113 CreditCard.for(iq, customer, tel)
114 when "code"
115 raise "TODO"
116 else
117 raise "Invalid activation method"
118 end
119 end
120
121 class Bitcoin
122 def initialize(iq, customer, tel)
123 @reply = iq.reply
124 reply.note_type = :info
125 reply.status = :completed
126
127 plan_name = iq.form.field("plan_name").value.to_s
128 @customer = customer.with_plan(plan_name)
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 def self.for(iq, customer, tel)
173 customer.payment_methods.then do |payment_methods|
174 if payment_methods.default_payment_method
175 Activate.new(iq, customer, tel)
176 else
177 new(iq, customer, tel)
178 end
179 end
180 end
181
182 def initialize(iq, customer, tel)
183 @customer = customer
184 @tel = tel
185
186 @reply = iq.reply
187 @reply.allowed_actions = [:next]
188 @reply.note_type = :info
189 @reply.note_text = "#{oob.desc}: #{oob.url}"
190 end
191
192 attr_reader :reply
193
194 def oob
195 oob = OOB.find_or_create(@reply.command)
196 oob.url = CONFIG[:credit_card_url].call(
197 @reply.to.stripped.to_s,
198 @customer.customer_id
199 )
200 oob.desc = "Add credit card, then return here and choose next"
201 oob
202 end
203
204 def write
205 COMMAND_MANAGER.write(@reply).then do |riq|
206 CreditCard.for(riq, @customer, @tel)
207 end
208 end
209
210 class Activate
211 def initialize(_iq, _customer, _tel)
212 raise "TODO"
213 end
214 end
215 end
216 end
217end