buy_account_credit_form.rb

 1# frozen_string_literal: true
 2
 3require_relative "trust_level_repo"
 4require_relative "credit_card_sale"
 5
 6class BuyAccountCreditForm
 7	# Returns a TrustLevelRepo instance, allowing for dependency injection.
 8	# Either creates a new instance given kwargs or returns the existing instance.
 9	# @param kwargs [Hash] keyword arguments.
10	# @option kwargs [TrustLevelRepo] :trust_level_repo An existing TrustLevelRepo instance.
11	# @return [TrustLevelRepo] An instance of TrustLevelRepo.
12	def self.trust_level_repo(**kwargs)
13		kwargs[:trust_level_repo] || TrustLevelRepo.new(**kwargs)
14	end
15
16	# Factory method to create a BuyAccountCreditForm for a given customer.
17	# It fetches the customer's trust level to determine the maximum top-up amount.
18	# @param customer [Customer] The customer for whom the form is being created.
19	# @return [EMPromise<BuyAccountCreditForm>] A promise that resolves with the new form instance.
20	def self.for(customer)
21		trust_level_repo.find(customer).then do |trust_level|
22			customer.payment_methods.then do |payment_methods|
23				new(customer.balance, payment_methods, trust_level.max_top_up_amount)
24			end
25		end
26	end
27
28	# Initializes a new BuyAccountCreditForm.
29	# @param balance [BigDecimal] The current balance of the customer.
30	# @param payment_methods [PaymentMethods] The available payment methods for the customer.
31	# @param max_top_up_amount [Numeric] The maximum amount the customer is allowed to top up, based on their trust level.
32	def initialize(balance, payment_methods, max_top_up_amount)
33		@balance = balance
34		@payment_methods = payment_methods
35		@max_top_up_amount = max_top_up_amount
36	end
37
38	# Generates the form template for topping up account credit.
39	# The form will include a range for the amount field, constrained by a minimum of $15
40	# and the customer's specific maximum top-up amount.
41	# @return [FormTemplate::OneRender] The rendered form template.
42	def form
43		FormTemplate.render(
44			:top_up,
45			balance: @balance,
46			payment_methods: @payment_methods,
47			range: [15, @max_top_up_amount]
48		)
49	end
50
51	def parse(form)
52		amount = form.field("amount")&.value&.to_s
53		amount_value = amount.to_f
54
55		raise AmountTooLowError.new(amount_value, 15) if amount_value < 15
56
57		{
58			payment_method: @payment_methods.fetch(
59				form.field("payment_method")&.value.to_i
60			),
61			amount: amount
62		}
63	end
64end