~singpolyma/sgx-jmp

1c36e692925bc827b2e3417c7f30b3255c423e55 — Christopher Vollick 8 months ago 6fb0be1
Admin Command Menu + Admin Financial View

I've added a new command to show financial information about the user.
But more importantly I've added an infinite admin subsystem which allows
me to go into a user and then run multiple commands on them.

For now it's just these two info commands, but in the future I'd like to
add mutative commands here.

Finally, since I sometimes look up multiple users in a pretty short
timeframe I made the menu open and if I put something into the list that
doesn't parse as one of the actions it instead switches the current user
so I don't have to do "cancel", "customer", and then put the next one
in.

I can just have the session open and put stuff in as needed.
A forms/admin_financial_info.rb => forms/admin_financial_info.rb +9 -0
@@ 0,0 1,9 @@
result!
title "Customer Financial Info"

field(
	var: "declines",
	label: "Declines",
	description: "out of 2",
	value: @info.declines.to_s
)

A forms/admin_menu.rb => forms/admin_menu.rb +14 -0
@@ 0,0 1,14 @@
form!
title "Menu"

field(
	var: "action",
	type: "list-single",
	open: true,
	label: "Pick an action",
	description: "or put a new customer info",
	options: [
		{ value: "info", label: "Customer Info" },
		{ value: "financial", label: "Customer Billing Information" }
	]
)

A forms/admin_payment_methods.rb => forms/admin_payment_methods.rb +10 -0
@@ 0,0 1,10 @@
result!
title "Customer Payment Methods"

unless @payment_methods.empty?
	field @payment_methods.to_list_single(label: "Credit Cards")
end

AltTopUpForm::HasBitcoinAddresses.new(@btc_addresses, desc: nil).each do |spec|
	field spec
end

A forms/admin_transaction_list.rb => forms/admin_transaction_list.rb +10 -0
@@ 0,0 1,10 @@
result!
title "Transactions"

table(
	@transactions,
	formatted_amount: "Amount",
	note: "Note",
	created_at: "Date",
	transaction_id: "Transaction ID"
)

A lib/admin_command.rb => lib/admin_command.rb +79 -0
@@ 0,0 1,79 @@
# frozen_string_literal: true

require_relative "customer_info_form"
require_relative "financial_info"
require_relative "form_template"

class AdminCommand
	def initialize(target_customer)
		@target_customer = target_customer
	end

	def start
		action_info.then { menu }
	end

	def reply(form)
		Command.reply { |reply|
			reply.allowed_actions = [:next]
			reply.command << form
		}
	end

	def menu
		reply(FormTemplate.render("admin_menu")).then do |response|
			handle(response.form.field("action").value)
		end
	end

	def handle(action)
		if respond_to?("action_#{action}")
			send("action_#{action}")
		else
			new_context(action)
		end.then { menu }
	end

	def new_context(q)
		CustomerInfoForm.new.parse_something(q).then do |new_customer|
			if new_customer.respond_to?(:customer_id)
				AdminCommand.new(new_customer).start
			else
				reply(new_customer.form)
			end
		end
	end

	def action_info
		@target_customer.admin_info.then do |info|
			reply(info.form)
		end
	end

	def action_financial
		AdminFinancialInfo.for(@target_customer).then do |financial_info|
			reply(FormTemplate.render(
				"admin_financial_info",
				info: financial_info
			)).then {
				pay_methods(financial_info)
			}.then {
				transactions(financial_info)
			}
		end
	end

	def pay_methods(financial_info)
		reply(FormTemplate.render(
			"admin_payment_methods",
			**financial_info.to_h
		))
	end

	def transactions(financial_info)
		reply(FormTemplate.render(
			"admin_transaction_list",
			transactions: financial_info.transactions
		))
	end
end

M lib/alt_top_up_form.rb => lib/alt_top_up_form.rb +3 -2
@@ 101,8 101,9 @@ class AltTopUpForm
	end

	class HasBitcoinAddresses
		def initialize(addrs)
		def initialize(addrs, desc: DESCRIPTION)
			@addrs = addrs
			@desc = desc
		end

		DESCRIPTION =


@@ 116,7 117,7 @@ class AltTopUpForm
				var: "btc_address",
				type: "fixed",
				label: "Bitcoin Addresses",
				description: DESCRIPTION,
				description: @desc,
				value: @addrs
			)
		end

A lib/financial_info.rb => lib/financial_info.rb +25 -0
@@ 0,0 1,25 @@
# frozen_string_literal: true

require "value_semantics/monkey_patched"

class AdminFinancialInfo
	value_semantics do
		transactions ArrayOf(CustomerFinancials::TransactionInfo)
		declines Integer
		btc_addresses ArrayOf(String)
		payment_methods PaymentMethods
	end

	def self.for(customer)
		EMPromise.all([
			customer.transactions, customer.declines,
			customer.payment_methods, customer.btc_addresses
		]).then do |transactions, declines, payment_methods, btc_addresses|
			new(
				transactions: transactions,
				declines: declines || 0,
				payment_methods: payment_methods, btc_addresses: btc_addresses
			)
		end
	end
end

M lib/payment_methods.rb => lib/payment_methods.rb +11 -1
@@ 50,7 50,13 @@ class PaymentMethods
		false
	end

	class Empty
	def to_a
		@methods
	end

	class Empty < PaymentMethods
		def initialize; end

		def default_payment_method; end

		def to_list_single(*)


@@ 60,5 66,9 @@ class PaymentMethods
		def empty?
			true
		end

		def to_a
			[]
		end
	end
end

M sgx_jmp.rb => sgx_jmp.rb +2 -5
@@ 67,6 67,7 @@ end

require_relative "lib/polyfill"
require_relative "lib/alt_top_up_form"
require_relative "lib/admin_command"
require_relative "lib/add_bitcoin_address"
require_relative "lib/backend_sgx"
require_relative "lib/bwmsgsv2_repo"


@@ 726,11 727,7 @@ Command.new(
		}.then { |response|
			CustomerInfoForm.new.find_customer(response)
		}.then do |target_customer|
			target_customer.admin_info.then do |info|
				Command.finish do |reply|
					reply.command << info.form
				end
			end
			AdminCommand.new(target_customer).start
		end
	end
}.register(self).then(&CommandList.method(:register))