buy_account_credit_form.rb

 1# frozen_string_literal: true
 2
 3require_relative "./xep0122_field"
 4
 5class BuyAccountCreditForm
 6	class AmountValidationError < StandardError
 7		def initialize(amount)
 8			super(
 9				"amount #{amount} must be in the range " \
10				"#{RANGE.first} through #{RANGE.last}"
11			)
12		end
13	end
14
15	def self.for(customer)
16		customer.payment_methods.then do |payment_methods|
17			new(customer.balance, payment_methods)
18		end
19	end
20
21	def initialize(balance, payment_methods)
22		@balance = balance
23		@payment_methods = payment_methods
24	end
25
26	RANGE = (15..1000).freeze
27
28	AMOUNT_FIELD =
29		XEP0122Field.new(
30			"xs:decimal",
31			range: RANGE,
32			var: "amount",
33			label: "Amount of credit to buy",
34			required: true
35		).field
36
37	def balance
38		{
39			type: "fixed",
40			value: "Current balance: $#{'%.2f' % @balance}"
41		}
42	end
43
44	def add_to_form(form)
45		form.type = :form
46		form.title = "Buy Account Credit"
47		form.fields = [
48			balance,
49			@payment_methods.to_list_single,
50			AMOUNT_FIELD
51		]
52	end
53
54	def parse(form)
55		amount = form.field("amount")&.value&.to_s
56		raise AmountValidationError, amount unless RANGE.include?(amount.to_i)
57
58		{
59			payment_method: @payment_methods.fetch(
60				form.field("payment_method")&.value.to_i
61			),
62			amount: amount
63		}
64	end
65end