~singpolyma/sgx-jmp

d0d8286a0be957b5bb26c16311ef5a6adc934b8d — Stephen Paul Weber 1 year, 8 months ago b9b0766
Command to migrate transitional status accounts

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.
4 files changed, 112 insertions(+), 15 deletions(-)

A forms/migrate_billing.rb
A lib/paypal_done.rb
M lib/registration.rb
M sgx_jmp.rb
A forms/migrate_billing.rb => forms/migrate_billing.rb +46 -0
@@ 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"
		}
	]
)

A lib/paypal_done.rb => lib/paypal_done.rb +14 -0
@@ 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

M lib/registration.rb => lib/registration.rb +23 -15
@@ 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

M sgx_jmp.rb => sgx_jmp.rb +29 -0
@@ 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