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