1# frozen_string_literal: true
2
3require_relative "expiring_lock"
4require_relative "transaction"
5
6class LowBalance
7 def self.for(customer)
8 return Locked.new unless customer.registered?
9
10 ExpiringLock.new(
11 "jmp_customer_low_balance-#{customer.customer_id}",
12 expiry: 60 * 60 * 24 * 7
13 ).with(-> { Locked.new }) do
14 customer.auto_top_up_amount.then do |auto_top_up_amount|
15 for_auto_top_up_amount(customer, auto_top_up_amount)
16 end
17 end
18 end
19
20 def self.for_auto_top_up_amount(customer, auto_top_up_amount)
21 if auto_top_up_amount.positive?
22 AutoTopUp.new(customer, auto_top_up_amount)
23 else
24 customer.btc_addresses.then do |btc_addresses|
25 new(customer, btc_addresses)
26 end
27 end
28 end
29
30 def initialize(customer, btc_addresses)
31 @customer = customer
32 @btc_addresses = btc_addresses
33 end
34
35 def notify!
36 m = Blather::Stanza::Message.new
37 m.from = CONFIG[:notify_from]
38 m.body =
39 "Your balance of $#{'%.4f' % @customer.balance} is low." \
40 "#{btc_addresses_for_notification}"
41 @customer.stanza_to(m)
42 end
43
44 def btc_addresses_for_notification
45 return if @btc_addresses.empty?
46
47 "\nYou can buy credit by sending any amount of Bitcoin to one of " \
48 "these addresses:\n#{@btc_addresses.join("\n")}"
49 end
50
51 class AutoTopUp
52 def initialize(customer, auto_top_up_amount)
53 @customer = customer
54 @auto_top_up_amount = auto_top_up_amount
55 @message = Blather::Stanza::Message.new
56 @message.from = CONFIG[:notify_from]
57 end
58
59 def sale
60 Transaction.sale(@customer, amount: @auto_top_up_amount).then do |tx|
61 tx.insert.then { tx }
62 end
63 end
64
65 def notify!
66 sale.then { |tx|
67 @message.body =
68 "Automatic top-up has charged your default " \
69 "payment method and added #{tx} to your balance."
70 }.catch { |e|
71 @message.body =
72 "Automatic top-up transaction for " \
73 "$#{@auto_top_up_amount} failed: #{e.message}"
74 }.then { @customer.stanza_to(@message) }
75 end
76 end
77
78 class Locked
79 def notify!; end
80 end
81end