registration.rb

  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