1# frozen_string_literal: true
2
3class CustomerFinancials
4 def initialize(customer_id)
5 @customer_id = customer_id
6 end
7
8 def payment_methods
9 EMPromise.all([
10 BRAINTREE
11 .customer
12 .find(@customer_id)
13 .catch { OpenStruct.new(payment_methods: []) },
14 REDIS.smembers("block_credit_cards")
15 ]).then { |(braintree, badcards)| PaymentMethods.for(braintree, badcards) }
16 end
17
18 def btc_addresses
19 REDIS.smembers("jmp_customer_btc_addresses-#{@customer_id}")
20 end
21
22 def add_btc_address
23 REDIS.spopsadd([
24 "jmp_available_btc_addresses",
25 "jmp_customer_btc_addresses-#{@customer_id}"
26 ]).then do |addr|
27 ELECTRUM.notify(
28 addr,
29 CONFIG[:electrum_notify_url].call(addr, @customer_id)
30 )
31 addr
32 end
33 end
34
35 def declines
36 REDIS.get("jmp_pay_decline-#{@customer_id}").then(&:to_i)
37 end
38
39 def mark_decline
40 REDIS.incr("jmp_pay_decline-#{@customer_id}").then do
41 REDIS.expire("jmp_pay_decline-#{@customer_id}", 60 * 60 * 24)
42 end
43 end
44
45 def set_declines(num)
46 if num.positive?
47 REDIS.set("jmp_pay_decline-#{@customer_id}", num)
48 else
49 REDIS.del("jmp_pay_decline-#{@customer_id}")
50 end
51 end
52
53 class TransactionInfo
54 value_semantics do
55 transaction_id String
56 created_at Time
57 amount BigDecimal
58 note String, coerce: ->(x) { x || "" }
59 end
60
61 def formatted_amount
62 "$%.4f" % amount
63 end
64 end
65
66 TRANSACTIONS_SQL = <<~SQL
67 SELECT
68 transaction_id,
69 created_at,
70 amount,
71 note
72 FROM transactions
73 WHERE customer_id = $1
74 ORDER BY created_at;
75 SQL
76
77 def transactions
78 txns = DB.query_defer(TRANSACTIONS_SQL, [@customer_id])
79
80 txns.then do |rows|
81 rows.map { |row|
82 TransactionInfo.new(**row.transform_keys(&:to_sym))
83 }
84 end
85 end
86end