Command to migrate transitional status accounts

Stephen Paul Weber created

Currently we tell users to use the web activation for this, but we'd like the we
activation to go away very soon and will still need a path for them.

Change summary

forms/migrate_billing.rb | 46 +++++++++++++++++++++++++++++++++++++++++
lib/paypal_done.rb       | 14 ++++++++++++
lib/registration.rb      | 38 ++++++++++++++++++++-------------
sgx_jmp.rb               | 29 ++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 15 deletions(-)

Detailed changes

forms/migrate_billing.rb 🔗

@@ -0,0 +1,46 @@
+form!
+title "Switch from PayPal or expired trial"
+instructions <<~I
+	This command will allow you to switch from your legacy PayPal or trial billing to the new pre-paid balance system.
+
+	PayPal users will receive credit equivalent to one free month after migrating.  PLEASE be sure to contact support after you are done and let them know your PayPal email address.
+I
+
+field(
+	var: "activation_method",
+	type: "list-single",
+	label: "Choose a payment method to deposit your first " \
+	       "$#{CONFIG[:activation_amount]}",
+	required: true,
+	options: [
+		{
+			value: "credit_card",
+			label: "Credit Card"
+		},
+		{
+			value: "bitcoin",
+			label: "Bitcoin"
+		},
+		{
+			value: "mail",
+			label: "Mail or eTransfer"
+		}
+	]
+)
+
+field(
+	var: "plan_name",
+	type: "list-single",
+	label: "What currency should your account balance be in?",
+	required: true,
+	options: [
+		{
+			value: "cad_beta_unlimited-v20210223",
+			label: "Canadian Dollars"
+		},
+		{
+			value: "usd_beta_unlimited-v20210223",
+			label: "United States Dollars"
+		}
+	]
+)

lib/paypal_done.rb 🔗

@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class PaypalDone
+	MESSAGE =
+		"\n\nPayPal users must now go to https://www.paypal.com/myaccount/autopay/ " \
+		"and cancel their PayPal subscription to JMP. Then contact support with " \
+		"your PayPal email address."
+
+	def initialize(*); end
+
+	def write
+		Command.finish(MESSAGE)
+	end
+end

lib/registration.rb 🔗

@@ -146,12 +146,12 @@ class Registration
 			@kinds ||= {}
 		end
 
-		def self.for(iq, customer, tel)
+		def self.for(iq, customer, tel, final_message: nil, finish: Finish)
 			plan_name = iq.form.field("plan_name").value.to_s
 			customer = customer.with_plan(plan_name)
 			kinds.fetch(iq.form.field("activation_method")&.value&.to_s&.to_sym) {
 				raise "Invalid activation method"
-			}.call(customer, tel)
+			}.call(customer, tel, final_message: final_message, finish: finish)
 		end
 
 		class Bitcoin
@@ -159,10 +159,11 @@ class Registration
 
 			THIRTY_DAYS = 60 * 60 * 24 * 30
 
-			def initialize(customer, tel)
+			def initialize(customer, tel, final_message: nil, **)
 				@customer = customer
 				@customer_id = customer.customer_id
 				@tel = tel
+				@final_message = final_message
 			end
 
 			attr_reader :customer_id, :tel
@@ -194,7 +195,9 @@ class Registration
 					BTC_SELL_PRICES.public_send(@customer.currency.to_s.downcase)
 				]).then do |(addr, _, rate)|
 					min = CONFIG[:activation_amount] / rate
-					Command.finish(note_text(min, addr), status: :canceled)
+					Command.finish(
+						note_text(min, addr) + @final_message.to_s, status: :canceled
+					)
 				end
 			end
 
@@ -210,19 +213,20 @@ class Registration
 		class CreditCard
 			Payment.kinds[:credit_card] = ->(*args) { self.for(*args) }
 
-			def self.for(customer, tel)
+			def self.for(customer, tel, finish: Finish, **)
 				customer.payment_methods.then do |payment_methods|
 					if (method = payment_methods.default_payment_method)
-						Activate.new(customer, method, tel)
+						Activate.new(customer, method, tel, finish: finish)
 					else
-						new(customer, tel)
+						new(customer, tel, finish: finish)
 					end
 				end
 			end
 
-			def initialize(customer, tel)
+			def initialize(customer, tel, finish: Finish)
 				@customer = customer
 				@tel = tel
+				@finish = finish
 			end
 
 			def oob(reply)
@@ -241,15 +245,16 @@ class Registration
 					reply.note_type = :info
 					reply.note_text = "#{oob(reply).desc}: #{oob(reply).url}"
 				}.then do
-					CreditCard.for(@customer, @tel).then(&:write)
+					CreditCard.for(@customer, @tel, finish: @finish).then(&:write)
 				end
 			end
 
 			class Activate
-				def initialize(customer, payment_method, tel)
+				def initialize(customer, payment_method, tel, finish: Finish)
 					@customer = customer
 					@payment_method = payment_method
 					@tel = tel
+					@finish = finish
 				end
 
 				def write
@@ -269,7 +274,7 @@ class Registration
 					tx.insert.then {
 						@customer.bill_plan
 					}.then do
-						Finish.new(@customer, @tel).write
+						@finish.new(@customer, @tel).write
 					end
 				end
 
@@ -301,7 +306,7 @@ class Registration
 						reply.note_type = :error
 						reply.note_text = "#{reply_oob.desc}: #{reply_oob.url}"
 					}.then do
-						CreditCard.for(@customer, @tel).then(&:write)
+						CreditCard.for(@customer, @tel, finish: @finish).then(&:write)
 					end
 				end
 			end
@@ -319,7 +324,7 @@ class Registration
 				required: true
 			}].freeze
 
-			def initialize(customer, tel, error: nil)
+			def initialize(customer, tel, error: nil, **)
 				@customer = customer
 				@tel = tel
 				@error = error
@@ -386,7 +391,9 @@ class Registration
 		class Mail
 			Payment.kinds[:mail] = method(:new)
 
-			def initialize(_customer, _tel); end
+			def initialize(_customer, _tel, final_message: nil, **)
+				@final_message = final_message
+			end
 
 			def form
 				form = Blather::Stanza::X.new(:result)
@@ -395,7 +402,8 @@ class Registration
 					"Activate your account by sending at least " \
 					"$#{CONFIG[:activation_amount]}\nWe support payment by " \
 					"postal mail or, in Canada, by Interac eTransfer.\n\n" \
-					"You will receive a notification when your payment is complete."
+					"You will receive a notification when your payment is complete." \
+					"#{@final_message}"
 
 				form.fields = fields.to_a
 				form

sgx_jmp.rb 🔗

@@ -81,6 +81,7 @@ require_relative "lib/expiring_lock"
 require_relative "lib/em"
 require_relative "lib/low_balance"
 require_relative "lib/payment_methods"
+require_relative "lib/paypal_done"
 require_relative "lib/registration"
 require_relative "lib/transaction"
 require_relative "lib/tel_selections"
@@ -608,6 +609,34 @@ Command.new(
 	end
 }.register(self).then(&CommandList.method(:register))
 
+Command.new(
+	"migrate billing",
+	"Switch from PayPal or expired trial to new billing",
+	list_for: ->(tel:, customer:, **) { tel && !customer&.currency }
+) {
+	EMPromise.all([
+		Command.customer.then { |c| EMPromise.all([c, c.registered?.then(&:phone)]) },
+		Command.reply do |reply|
+			reply.allowed_actions = [:next]
+			reply.command << FormTemplate.render("migrate_billing")
+		end
+	]).then do |((customer, tel), iq)|
+		Registration::Payment.for(
+			iq, customer, tel,
+			final_message: PaypalDone::MESSAGE,
+			finish: PaypalDone
+		).then(&:write).catch_only(Command::Execution::FinalStanza) do |s|
+			BLATHER.join(CONFIG[:notify_admin], "sgx-jmp")
+			BLATHER.say(
+				CONFIG[:notify_admin],
+				"#{customer.customer_id} migrated to #{customer.currency}",
+				:groupchat
+			)
+			EMPromise.reject(s)
+		end
+	end
+}.register(self).then(&CommandList.method(:register))
+
 command sessionid: /./ do |iq|
 	COMMAND_MANAGER.fulfill(iq)
 end